Json.net:按对象 ID 合并两个 json 数组

mar*_*nun 5 c# json json.net

例如,我想通过对象 id 来打乱 json 数组。假设我有这个 json 数组:

 [{"Id":"1", "a":"1", "b":"2"},
  {"Id":"2", "a":"3", "b":"1"},
  {"Id":"3", "a":"5", "b":"1"}]
Run Code Online (Sandbox Code Playgroud)

我想用这个数组更新它

 [{"Id":"1", "a":"32", "b":"42"},
 {"Id":"2", "a":"3", "b":"1", "c":"23"},
  {"Id":"12", "a":"12", "b":"45"}]
Run Code Online (Sandbox Code Playgroud)

预期结果应该是:

[{"Id":"1", "a":"32", "b":"42"},
  {"Id":"2", "a":"3", "b":"1", "c":"23"},
  {"Id":"3", "a":"5", "b":"1"},
  {"Id":"12", "a":"12", "b":"45"}]
Run Code Online (Sandbox Code Playgroud)

Ale*_*nov 2

我认为用 C# 可以轻松完成。如果您将实体映射到类似的东西:

[DataContract]
public class Entity
{
    [DataMember(Name = "Id")]
    public string Id { get; set; }

    [DataMember(Name = "a")]
    public int? A { get; set; }

    [DataMember(Name = "b")]
    public int? B { get; set; }

    [DataMember(Name = "c")]
    public int? C { get; set; }
}
Run Code Online (Sandbox Code Playgroud)

我认为使用 LINQ 不可能执行所需的操作,但旧的 foreach 可以解决您的问题。

编辑:实际上在查看@vadim-gremyachev 答案后,我认为可以使用 LINQ 很好地完成:

var l1 = JsonConvert.DeserializeObject<IList<Entity>>(
    @"[{""Id"":""1"", ""a"":""1"", ""b"":""2""}, 
       {""Id"":""2"", ""a"":""3"", ""b"":""1""}, 
       {""Id"":""3"", ""a"":""5"", ""b"":""1""}]");

var l2 = JsonConvert.DeserializeObject<IList<Entity>>(
    @"[{""Id"":""1"", ""a"":""32"", ""b"":""42""},
       {""Id"":""2"", ""a"":""3"", ""b"":""1"", ""c"":""23""},
       {""Id"":""12"", ""a"":""12"", ""b"":""45""}]");

// LINQ
var res = l1.Concat(l2).GroupBy(x => x.Id).Select(x => x.Last()).ToList();

// Foraech
var res2 = new List<Entity>(l1);
foreach (var l2Entity in l2)
{
    var resEntity = res2.FirstOrDefault(x => x.Id == l2Entity.Id);
    if (resEntity == null)
    {
        res2.Add(l2Entity);
    }
    else
    {
        res2[res2.IndexOf(resEntity)] = l2Entity;
    }
}
Run Code Online (Sandbox Code Playgroud)

然后你可以将你的res列表序列化回 JSON 就完成了:

var json = JsonConvert.SerializeObject(res);
Run Code Online (Sandbox Code Playgroud)

生成的 JSON 将是:

[
    {"Id":"1","a":32,"b":42},
    {"Id":"2","a":3,"b":1,"c":23},
    {"Id":"3","a":5,"b":1},
    {"Id":"12","a":12,"b":45}
]
Run Code Online (Sandbox Code Playgroud)

您也可以使用l1而不创建res,当然这取决于您的情况。您可能还想在合并完成后按键对结果集合进行排序。