C# 读取JSON数据并根据条件循环数据以获得特定值
我一直在尝试根据给定的时间获取periods数组中的标题、描述、开始和结束日期,我有以下JSON数据(以下变量名为\u JSON): 更新: 我想做的是在periods json数组中获取标题、描述、开始和结束日期,它的条件将基于periods json数组中的开始和结束日期C# 读取JSON数据并根据条件循环数据以获得特定值,c#,arrays,json,linq,C#,Arrays,Json,Linq,我一直在尝试根据给定的时间获取periods数组中的标题、描述、开始和结束日期,我有以下JSON数据(以下变量名为\u JSON): 更新: 我想做的是在periods json数组中获取标题、描述、开始和结束日期,它的条件将基于periods json数组中的开始和结束日期 [ { "ID": "1", "Title": "First Title", "Description": "First Description",
[
{
"ID": "1",
"Title": "First Title",
"Description": "First Description",
"Periods": [
{
"StartDate": "2017-04-23 15:30",
"EndDate": "2017-04-23 15:40"
},
{
"StartDate": "2017-04-23 15:42",
"EndDate": "2017-04-23 15:45"
},
{
"StartDate": "2017-04-23 15:47",
"EndDate": "2017-04-23 15:50"
}
]
},
{
"ID" : "2",
"Title": "Second Title",
"Description": "Second Description",
"Periods": [
{
"StartDate": "2017-04-23 15:52",
"EndDate": "2017-04-23 15:55"
},
{
"StartDate": "2017-04-23 15:57",
"EndDate": "2017-04-23 16:00"
},
{
"StartDate": "2017-04-23 16:02",
"EndDate": "2017-04-23 16:05"
}
]
}
]
这是我的代码:
public sealed class Information
{
public List<Period> Periods;
public string Title;
public string Description;
public int ID;
}
public sealed class Period
{
public DateTime StartDate;
public DateTime EndDate;
}
var informations = JsonConvert.DeserializeObject<List<Information>>(_json);
var information = GetData(informations, DateTime.Now);
private Information GetData(List<Information> informations, DateTime dateToCheck)
{
return informations.Select(x =>
{
x.Periods = x.Periods
.TakeWhile(y => dateToCheck >= y.StartDate
&& dateToCheck < y.EndDate)
.ToList();
if (x.Periods.Count > 0)
return x;
else
return null;
}).FirstOrDefault();
}
谢谢我想你需要一个
在哪里
,而不是TakeWhile
:
x.Periods = x.Periods
.Where(y => dateToCheck >= y.StartDate
&& dateToCheck < y.EndDate)
.ToList();
根据MSDN,您的查询存在以下问题:- 只要指定了条件,就从序列返回元素 对。元素的索引用于谓词的逻辑中 功能 因此,在查询中,它只进行检查,直到找到正确的匹配项,然后忽略所有数据。相反,您需要在整个
期间检查您的状况
您可以使用FirstOrDefault
简化查询,它应该会给出正确的结果:-
return informations.FirstOrDefault(y => dateToCheck >= y.StartDate
& dateToCheck < y.EndDate);
返回信息.FirstOrDefault(y=>dateToCheck>=y.StartDate
&dateToCheck
如果未找到匹配项,则返回null;否则,如果找到匹配项,则返回第一个信息对象
如果要返回所有匹配的期间
,请使用Where
instaed,方法返回类型应更改为IEnumerable
,而不是信息
,有一种更具可读性的方法来编写查询(有效):
私有静态信息GetData(列表信息、日期时间日期检查)
{
返回(来自信息中的信息)
从信息期间中的期间
其中dateToCheck>=period.StartDate&&
dateToCheck
@Serenity不客气!我很高兴我帮了忙:)嗨,在我再次测试它之后,句点现在起作用了,但是信息只是查看JSON的第一个数据,在我将函数设置为IEnumerable之后,它在JSON数据列表中循环,但直到最后一个JSON数组循环通过它才停止,回到我上面的问题:-我想做的是获取periods json数组中的标题、描述、开始和结束日期,其条件将基于periods json数组中的开始和结束日期。Thanks@Serenity请检查我的更新。我想你想要的是这个,让我知道。谢谢,我已经在上面的问题上贴了图片。请帮助查看它和预期输出。谢谢不幸的是,您的更新不适用于我,它获取了JSON数组的信息列表。对不起,谢谢你的帮助。@Serenity我很抱歉,但我还不清楚你在找什么?如果每个ID都有匹配周期,是否需要第一个匹配周期?如果任何ID有任何匹配周期,您是否想要第一个匹配周期?(如果您有ID 1、2、3、4和5,并且对于ID 2和4有一个匹配周期,您只想要ID 2的匹配周期,因为它将首先被处理)?@Serenity-没有问题。我很高兴它帮助了你。嗨,在我再次测试它之后,句点现在开始工作了,但是信息只是查看JSON的第一个数据,在我将函数设置为IEnumerable之后,它在JSON数据列表中循环,但直到最后一个JSON数组循环通过它才停止,回到我上面的问题:-我想做的是获取periods json数组中的标题、描述、开始和结束日期,其条件将基于periods json数组中的开始和结束日期。Thanks@Serenity-我不清楚您所说的条件是什么,它将基于json数组中的开始和结束日期。您能否根据您的输入显示您正在寻找的预期输出。这会让事情变得更清楚。嗨,我已经在上面的问题上贴了图片。请帮助查看它和预期输出。谢谢
private Information GetFirstMatchingInformationByPeriod(
List<Information> informations
, DateTime dateToCheck)
{
// Find the first information that match your search criteria
var information = informations.FirstOrDefault(information
=> information.Periods
.Any(period
=> period.dateToCheck >= period.StartDate
&& period.dateToCheck < period.EndDate);
// If not any found, return null.
if(information == null) return null;
var firstMatchingPeriod = information.Periods
.First(period => dateToCheck >= period.StartDate
&& dateToCheck < period.EndDate);
// Information found.
// Change it's periods with a List containin only the first matching period.
information.Periods = new List<Period>{ firstMatchingPeriod } ;
return information;
}
return informations.FirstOrDefault(y => dateToCheck >= y.StartDate
& dateToCheck < y.EndDate);
private static Information GetData(List<Information> informations, DateTime dateToCheck)
{
return (from info in informations
from period in info.Periods
where dateToCheck >= period.StartDate &&
dateToCheck < period.EndDate
select info).FirstOrDefault();
}