【问题标题】:C# parse JSON group by typeC# 按类型解析 JSON 组
【发布时间】:2017-07-25 10:51:39
【问题描述】:

这是 JSON

[
    {
        "name": "TeamA",
        "zone": "North",
        "id": 12,
        "players": [
            {
                "name": "TAPlayer1",
                "type": "Keeper"
            },
            {
                "name": "TAPlayer2",
                "type": "Bowler"
            }
        ]
    },
    {
        "name": "TeamB",
        "zone": "South",
        "id": 20,
        "players": [
            {
                "name": "TBPlayer1",
                "type": "Keeper"
            }
        ]
    },
    {
        "name": "TeamC",
        "zone": "South",
        "id": 45,
        "players": null
    },
    {
        "name": "TeamD",
        "zone": "North",
        "id": 40,
        "players": [
            {
                "name": "Tom",
                "type": "Keeper"
            },
            {
                "name": "Max",
                "type": "Keeper"
            },
            {
                "name": "Sam",
                "type": "Bowler"
            },
            {
                "name": "Jim",
                "type": "Keeper"
            }
        ]
    }
]

我想要这样的结果(使用球员类型守门员按区域分组)

North
TAPlayer1
Tom
Max

South
TBPlayer1

我试图这样解析

public class Player
    {
        public string name { get; set; }
        public string type { get; set; }
    }

    public class Teams
    {
        public string name { get; set; }
        public string zone { get; set; }
        public int id { get; set; }
        public List<Player> players { get; set; }
    }
        Teams[] ownersArray = JsonConvert.DeserializeObject<Teams[]>(json);

我想按区域显示结果组,类型应该是 keeper。任何建议将不胜感激。

提前致谢。

【问题讨论】:

  • 不要为此使用动态。如果你使用动态,intellisense 帮不了你。

标签: c# .net json c#-4.0 json.net


【解决方案1】:

反序列化 JSON 后

Teams[] teams = JsonConvert.DeserializeObject<Teams[]>(json);

您可以使用 LINQ 按区域分组

var groupedByZone = teams.Where(t => t.players != null).GroupBy(t => t.zone);

我们希望从每个组中获得球员

var players = groupedByZone.Select(g => new { 
    name = g.Key, 
    players = g.SelectMany(t => t.players).Where(p => p.type == "Keeper").ToArray() 
});

这一切都可以在一个语句中完成

var keepersByZone = teams.Where(t => t.players != null)
                         .GroupBy(team => team.zone)
                         .Select(g => new { 
                             name = g.Key, 
                             players = g.SelectMany(team => team.players)
                                        .Where(player => plapyer.type == "Keeper")
                                        .OrderBy(player => player.name)
                                        .ToArray() 
                         });

显示输出

foreach(var zone in keepersByZone) {
    Console.WriteLine(zone.name);
    foreach(var player in zone.players) {
        Console.WriteLine(player.name);
    }
    Console.WriteLine();
}

【讨论】:

    【解决方案2】:

    试试他的。这将返回所有区域,其中有任何守门员。也许有帮助

    public class Serilizer
    {
      public List<Zone> TeamsInZone(string j)
      {
         var a = JsonConvert.DeserializeObject<List<Zone>>(j);
         var list = a.Select(s =>s).Where(t => t.players != null && t.players.Any(u=>u.type == "Keeper")).ToList();
    return list;
      }
    }
    

    【讨论】:

      【解决方案3】:

      我注意到您已经实施了反序列化步骤,因此要显示按区域分组的“keeper”用户列表,您需要使用多个 linq 语句。第一步是获取唯一的“区域”列表

      string[] Zones = (from t in ownersArray select t.zone).Distinct().ToArray();
      

      遍历唯一列表中的每个区域,输出区域名称。接下来在该区域内找到一支球队,遍历球队并打印每个守门员的球员

            foreach (string Zone in Zones) {
                  Console.WriteLine("Zone: " + Zone);
                  // Find teams in this zone
                  Teams[] Ts = (from t in ownersArray where t.zone == Zone select t).ToArray();
                  foreach (Teams T in Ts.Where(x=>x.players != null)) {
                      foreach (Player P in T.players.Where(x=>x.type == "Keeper").OrderBy(x=>x.name)) {
                          // print players in this zone who are keepers
                          Console.WriteLine(P.name);
                      }
                  }
              }
      

      【讨论】:

      • 谢谢,看起来不错,如果我想按每个区域中的玩家字母顺序排序怎么办?
      • 只需添加 .OrderBy(x=>x.name) 我已经编辑了完整的代码
      • 我只是得到区域,而玩家没有打印
      • 我拼写错误,我已经更新了代码,一切正常
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-06-04
      • 1970-01-01
      • 2013-12-25
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多