当前位置: 动力学知识库 > 问答 > 编程问答 >

json - Merging arrays of dictionaries

问题描述:

Given the following two arrays of dictionaries, how can I merge them such that the resulting array of dictionaries contains only those dictionaries whose version is greatest?

data1 = [{'id': 1, 'name': 'Oneeee', 'version': 2},

{'id': 2, 'name': 'Two', 'version': 1},

{'id': 3, 'name': 'Three', 'version': 2},

{'id': 4, 'name': 'Four', 'version': 1},

{'id': 5, 'name': 'Five', 'version': 1}]

data2 = [{'id': 1, 'name': 'One', 'version': 1},

{'id': 2, 'name': 'Two', 'version': 1},

{'id': 3, 'name': 'Threeee', 'version': 3},

{'id': 6, 'name': 'Six', 'version': 2}]

The merged result should look like this:

data3 = [{'id': 1, 'name': 'Oneeee', 'version': 2},

{'id': 2, 'name': 'Two', 'version': 1},

{'id': 3, 'name': 'Threeee', 'version': 3},

{'id': 4, 'name': 'Four', 'version': 1},

{'id': 5, 'name': 'Five', 'version': 1},

{'id': 6, 'name': 'Six', 'version': 2}]

网友答案:

How about the following:

//define data1 and Data2
var data1 = new[]{
                   new {id = 1, name = "Oneeee", version = 2},
                   new {id = 2, name = "Two", version = 1},
                   new {id = 3, name = "Three", version = 2},
                   new {id = 4, name = "Four", version = 1},
                   new {id = 5, name ="Five", version = 1}
                 };

var data2 = new[] {
                   new {id = 1,  name = "One", version = 1},
                   new {id = 2, name = "Two", version = 1},
                   new {id = 3, name = "Threeee", version = 3},
                   new {id = 6, name = "Six", version = 2}
                 };
//create a dictionary to handle lookups     
var dict1 = data1.ToDictionary (k => k.id);
var dict2 = data2.ToDictionary (k => k.id);

// now query the data
var q = from k in dict1.Keys.Union(dict2.Keys)
        select
                dict1.ContainsKey(k) ? 
                  (
                    dict2.ContainsKey(k) ?
                    (
                      dict1[k].version > dict2[k].version ? dict1[k] : dict2[k]
                    ) :
                    dict1[k]
                  ) :
                  dict2[k];

// convert enumerable back to array
var result = q.ToArray();

Alternative solution that is database friendly if data1 and data2 are tables....

 var q  = (
            from d1 in data1
            join d2 in data2 on d1.id equals d2.id into data2j
            from d2j in data2j.DefaultIfEmpty()
            where d2j == null || d1.version >= d2j.version
            select d1
          ).Union(
            from d2 in data2
            join d1 in data1 on d2.id equals d1.id into data1j
            from d1j in data1j.DefaultIfEmpty()
           where d1j == null || d2.version > d1j.version
           select d2
          );

  var result = q.ToArray();
网友答案:

Assume you have some class like (JSON.NET attributes used here):

public class Data
{
    [JsonProperty("id")]
    public int Id { get; set; }
    [JsonProperty("name")]
    public string Name { get; set; }
    [JsonProperty("version")]
    public int Version { get; set; }
}

You can parse you JSON to arrays of this Data objects:

var str1 = @"[{'id': 1, 'name': 'Oneeee', 'version': 2},
              {'id': 2, 'name': 'Two', 'version': 1},
              {'id': 3, 'name': 'Three', 'version': 2},
              {'id': 4, 'name': 'Four', 'version': 1},
              {'id': 5, 'name': 'Five', 'version': 1}]";

var str2 = @"[{'id': 1, 'name': 'One', 'version': 1},
              {'id': 2, 'name': 'Two', 'version': 1},
              {'id': 3, 'name': 'Threeee', 'version': 3},
              {'id': 6, 'name': 'Six', 'version': 2}]";

var data1 = JsonConvert.DeserializeObject<Data[]>(str1);
var data2 = JsonConvert.DeserializeObject<Data[]>(str2);

So, you can concat these two arrays, group data items by id and select from each group item with highest version:

var data3 = data1.Concat(data2)
                 .GroupBy(d => d.Id)
                 .Select(g => g.OrderByDescending(d => d.Version).First())
                 .ToArray(); // or ToDictionary(d => d.Id)

Result (serialized back to JSON):

[
  { "id": 1, "name": "Oneeee", "version": 2 },
  { "id": 2, "name": "Two", "version": 1 },
  { "id": 3, "name": "Threeee", "version": 3 },
  { "id": 4, "name": "Four", "version": 1 },
  { "id": 5, "name": "Five", "version": 1 },
  { "id": 6, "name": "Six", "version": 2 }
]
分享给朋友:
您可能感兴趣的文章:
随机阅读: