简体   繁体   English

使用C#访问JSON中的多个数组

[英]Accessing multiple arrays in JSON using C#

My JSON looks like this: 我的JSON看起来像这样:

    {"2013" : [
        { "date":"2013-01-09 12:00:00","height":0 },
        { "date":"2013-01-19 12:00:00","height":3 },
        { "date":"2013-01-29 12:00:00","height":2 }],
    "2012" : [
        { "date":"2012-02-09 12:00:00","height":0 },
        { "date":"2012-02-19 12:00:00","height":4 },
        { "date":"2012-02-29 12:00:00","height":2 }],
    "2011" : [
        { "date":"2011-03-09 12:00:00","height":3 },
        { "date":"2011-03-19 12:00:00","height":8 },
        { "date":"2011-03-29 12:00:00","height":2 }]
   }

What I am trying to do is get all of the dates and height, but I am only able to do it per year using this code: 我想做的是获取所有日期和高度,但是我每年只能使用以下代码来做到这一点:

    public class Report
    {
        public DateTime Date { get; set; }
        public int Height { get; set; }
    }

    JObject data = JObject.Parse(sr);
    var postTitles = from p in data["2013"]
                     select new Report
                     {
                         Date = DateTime.Parse((string)p["date"]),
                         Height = (int)p["height"]
                     };

I was thinking of using a for loop but trying a variable inside data[" "] won't work. 我当时在考虑使用for循环,但尝试在data [“”]内部进行变量操作将不起作用。 I was also thinking of doing var postTitles += statement but it is not allowed as well. 我也正在考虑执行var postTitles + =语句,但也不允许这样做。 Any ideas on how I should go about this? 关于我应该如何处理的任何想法? I am using JSON.NET and it is suggested that I do a class per year (ie 2013, 2012, 2011) but I want them under one class to make it easier to manipulate data. 我正在使用JSON.NET,建议我每年做一堂课(即2013、2012、2011),但我希望它们在一个课下,以便于操作数据。

I am not that great with the LINQ syntax you are using but what you want to do is create a list from many lists. 我对您使用的LINQ语法不是很好,但是您想要做的就是从许多列表中创建一个列表。 So you want to use the SelectMany mapping operation from LINQ. 因此,您想使用LINQ的SelectMany映射操作。

var postTitles = data.Children()
        .SelectMany(subitems => subitems.First)
        .Select(dataOfYear =>
            new Report
                {
                    Date = DateTime.Parse((string)dataOfYear ["date"]),
                    Height = (int)dataOfYear ["height"]
                }
            );

If you want only the first 100 reports of every year you could do it like this: 如果您只需要每年的前100个报告,则可以这样做:

var postTitles = data.Children()
        .SelectMany(subitems => subitems.First)
        .Take(100)
        .Select(dataOfYear =>
            new Report
                {
                    Date = DateTime.Parse((string)dataOfYear ["date"]),
                    Height = (int)dataOfYear ["height"]
                }
            );

Or if you just want to free up the UI thread you could run this in a background thread: 或者,如果您只想释放UI线程,则可以在后台线程中运行它:

var postTitles = await Task.Run(() => data.Children()
        .SelectMany(subitems => subitems.First)
        .Select(dataOfYear =>
            new Report
                {
                    Date = DateTime.Parse((string)dataOfYear ["date"]),
                    Height = (int)dataOfYear ["height"]
                }
            ));

I turned and twisted Mark's anwer somewhat and came up with this: 我转过头来扭了一下马克的烦恼,然后想到了:

var postTitles = data.Children() // Select array container properties, like "2013"
        .SelectMany(x => x.First) // Select each subitem from every array
        .Select(r => // Create a report for each item
            new Report
                {
                    Date = DateTime.Parse((string)r["date"]),
                    Height = (int)r["height"]
                }
            );

Hopefully the inline comments will explain the logic sufficiently. 希望内联注释能够充分解释逻辑。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM