Json合并两个文件带来很大价值

时间:2019-02-19 14:09:48

标签: c# json

这是两个json示例。

我想将此json合并到一个文件中。 如果键存在于一个未经考虑就组合的值中,则很难仅替换具有高价值的值。

第一个样本。

 {
      "employees": [
        {
          "firstName": "Tom",
          "HighValue": "3"
        },
        {
          "firstName": "Maria",
          "HighValue": "4"
        },
        {
          "firstName": "Robert",
          "HighValue": "45"
        }
      ]
 }

第二个样本。

{
  "employees": [
    {
      "firstName": "Tom",
      "HighValue": "6"
    },
    {
      "firstName": "Maria",
      "HighValue": "4"
    },
    {
      "firstName": "Robert",
      "HighValue": "45"
    },
    {
      "firstName": "John",
      "HighValue": "1"
    }
  ]
}

我想要结果:

{
  "employees": [
    {
      "firstName": "Tom",
      "HighValue": "6"
    },
    {
      "firstName": "Maria",
      "HighValue": "4"
    },
    {
      "firstName": "Robert",
      "HighValue": "45"
    },
    {
      "firstName": "John",
      "HighValue": "1"
    }
  ]
}

目标是将两个样本Json合并为一个结果json。最好的方法是什么?

2 个答案:

答案 0 :(得分:0)

一种简单的方法是通过使用Json.NET之类的json框架来为您处理序列化/反序列化。
首先创建一个数据模型,可以将您的json数据反序列化到其中。我为此使用了在线工具json2csharp。这将为您提供以下模型:

public class Employee
{
    public string firstName { get; set; }
    public int HighValue { get; set; }
}

public class RootObject
{
    public List<Employee> employees { get; set; }
}

现在您可以简单地将json字符串反序列化为这样的对象:

string json1 = "";
string json2 = "";

var obj1 = JsonConvert.DeserializeObject<RootObject>(json1);
var obj2 = JsonConvert.DeserializeObject<RootObject>(json2);

在此步骤之后,您只需要遍历您的员工,检查它们是否同时存在于两个列表中,并相应地添加/更新它们:

foreach(var emp in obj2.employees)
{
    Employee existing = null;
    try
    {
        existing = obj1.employees.SingleOrDefault(e => e.firstName == emp.firstName);
    } 
    catch(Exception ex)
    {
        // The same employee exists multiple times in the first list
    }

    if(existing != null)
    {
        // obj1 already contains an employee with the given name, check which value is bigger
        if(existing.HighValue < emp.HighValue)
        {
            // The value of the existing employee is smaller 
            // -> Update the value with the value from the second object
            existing.HighValue = emp.HighValue;
        }
    }
    else
    {
        // obj1 does not already contain an employee with the given name, add the whole employee
        obj1.employees.Add(emp);
    }
}

现在obj1包含雇员的合并列表。
要将组合列表序列化回json,请执行以下操作:

var json = JsonConvert.SerializeObject(obj1);

答案 1 :(得分:0)

(从记录来看,JSON并不是我的强项之一,但我认为为您回答这将是一个很好的挑战)

以下代码使用Newtonsoft.Json将两个JSON样本都作为JObject,然后将两个样本合并在一起。然后,我使用LINQ分组并选择具有最高值的人员,然后输出一个新数组。

此解决方案的优点是,如果您只想使用C#进行合并,而不是将其用于其他任何逻辑,则无需反序列化为对象。 试试看:

var firstSample = JObject.Parse("Your first sample goes here");
var secondSample = JObject.Parse("Your second sample goes here");
var newJsonArray = new JArray(); //Makes new array for output

firstSample.Merge(secondSample); //Merges the firstSample JObject with secondSample JObject
var filteredJson = firstSample["employees"] //Makes new JObject with filtered values
    .GroupBy(x => x["firstName"]) // Groups by the first name
    .Select(x => x.Where(y => y["HighValue"] == x.Max(z => z["HighValue"]))) // Select the employee in each group with the highest value
    .ToList(); // Converts to a list out

foreach (var token in filteredJson)
{
    newJsonArray.Add(token); // For each selected employee, add it to the new array
}

var outputJson = new JObject(new JProperty("employees", newJsonArray)); // Composes the new JSon string