【问题标题】:Json combine two files for a large valueJson 将两个文件合并为一个大值
【发布时间】:2019-02-19 23:25:57
【问题描述】:

这里有两个 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。最好的方法是什么?

【问题讨论】:

  • 到目前为止你尝试过什么?包含您的代码。
  • 你试过 Newtonsoft.Json 了吗?它有很多有用的工具来完成您的要求。
  • 也许你可以:读取每个文件的所有内容,然后放入字符串中。使用这些字符串将 json 反序列化为带有名为 Newtonsoft.Json 的库的对象。根据需要操作这些对象并再次序列化为 json。
  • 你可以反序列化文件,然后做你想做的操作
  • @FelipeOriani,为什么将文件读入字符串然后反序列化字符串,而不是让反序列化器直接从文件中反序列化 JSON?

标签: c# json


【解决方案1】:

一种简单的方法是使用像 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);

【讨论】:

    【解决方案2】:

    (据记录,JSON 不是我的强项之一,但我认为为您回答这个问题将是一个很好的挑战)

    以下代码使用Newtonsoft.Json 将两个 JSON 样本作为 JObjects,然后将这两个样本合并在一起。然后我使用 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
    

    【讨论】:

      猜你喜欢
      • 2021-08-13
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2019-08-30
      • 2020-06-30
      相关资源
      最近更新 更多