Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/272.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/arrays/14.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 读取JSON数据并根据条件循环数据以获得特定值_C#_Arrays_Json_Linq - Fatal编程技术网

C# 读取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",

我一直在尝试根据给定的时间获取periods数组中的标题、描述、开始和结束日期,我有以下JSON数据(以下变量名为\u JSON):

更新:

我想做的是在periods json数组中获取标题、描述、开始和结束日期,它的条件将基于periods json数组中的开始和结束日期

[
    {
        "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();
}