【问题标题】:How can I merge two JObject? [duplicate]如何合并两个 JObject? [复制]
【发布时间】:2014-02-05 06:35:27
【问题描述】:

我有第一个 json:

{
    "data": [{
      "id": "id1",
      "field": "field1"
    }],
    "paging": {
        "prev": "link1",
    }
}

还有第二个:

{
    "data": [{
      "id": "id2",
      "field": "field2"
    }],
    "paging": {
        "prev": "link2",
    }
}

我想合并/联合这两个Data数组,例如:

{
    "data": [{
      "id": "id1",
      "field": "field1"
    },
    {
      "id": "id2",
      "field": "field2"
    }]  
}

(我现在不关心paging)。

我怎样才能又快又容易地做到这一点?这是我的尝试:

var final = JsonConvert.SerializeObject(new { data = json1["data"].Union(json2["data"]) }, Newtonsoft.Json.Formatting.Indented).ToString();

但引发异常:'Newtonsoft.Json.Linq.JArray' does not contains a definition of 'Union'

【问题讨论】:

    标签: c# .net json json.net


    【解决方案1】:

    Newtonsoft.Json 现在supports merging objects (old link):

    var dataObject1 = JObject.Parse(@"{
        ""data"": [{
            ""id"": ""id1"",
            ""field"": ""field1""
        }],
        ""paging"": {
            ""prev"": ""link1"",
        }
    }");
    var dataObject2 = JObject.Parse(@"{
        ""data"": [{
            ""id"": ""id2"",
            ""field"": ""field2""
        }],
        ""paging"": {
            ""prev"": ""link2"",
        }
    }");
    
    var mergeSettings = new JsonMergeSettings
    {
        MergeArrayHandling = MergeArrayHandling.Union
    };
    
    // method 1
    (dataObject1.SelectToken("data") as JArray).Merge(dataObject2.SelectToken("data"), mergeSettings);
    // method 2
    //dataObject1.Merge(dataObject2, mergeSettings);
        
    var mergedArray = dataObject1.SelectToken("data") as JArray;
        
    Console.WriteLine(mergedArray.ToString(Formatting.None));
    

    (用大脑编译器检查;))

    【讨论】:

    • 我想提一下现代,现代 C# 语法允许像 dataObject1.SelectToken("data") as JArray 这样丑陋的东西变得更干净:(JArray)dataObject1["data"]
    • @eltoro 我个人更喜欢这种方式:if (dataObject1["data"] is JArray jsonArr)。因为它允许您确保对象与类型匹配。否则,您可能会引入空对象引用异常。防御性编码 imo 是最好的。
    • 这个答案很有帮助,给了我一个提示,我可以如何替换 Javascript/ECMAScript “spread” 运算符来快速组合其他对象的对象;现在我可以从其他 JObject 中合并一个 JObject,太棒了!
    【解决方案2】:
    JArray dataOfJson1=json1.SelectToken("data");
    
    JArray dataofJson2=json2.SelectToken("data");
    
    foreach(JObject innerData in dataofJson2) 
    {
        dataOfJson1.Add(innerData);
    }
    

    【讨论】:

    • json1对象的数据类型是什么?
    • json1和json2的数据类型都是JObject,JObject json1 = JObject.Parse(data1); // 第一个 JSON 字符串 JObject json2 = JObject.Parse(data2); // 第二个 JSON 字符串
    【解决方案3】:

    对于那些(像我一样)不能使用新的 JSON.net 库的人。 下面的方法是我使用的。

    public static JObject mergeJsonObjects(List<JObject> objects) {
    
        JObject json = new JObject();
        foreach(JObject JSONObject in objects) {
            foreach(var property in JSONObject) {
                string name = property.Key;
                JToken value = property.Value;
    
                json.Add(property.Key, property.Value);
            }
        }
    
        return json;
    }
    

    该方法接受一个 JObject 列表并返回单个 JObject,简单而有效。

    【讨论】:

    • 只是好奇,内部 foreach 之后的两行是什么意思? string name = property.Key; JToken value = property.Value; 我假设它是用于调试或其他什么,或者您的代码通常对这些值执行某些操作,但您删除了它(并且忘记删除变量集代码)......但也许我错过了什么?
    【解决方案4】:

    一个可能的解决方案是:

    class Container
    {
        public List<IdField> data{get;set;}
    }
    
    class IdField
    {
        public string id{get;set;}
        public string field{get;set;}
    }
    
    
    string s1 = "{ \"data\": [{ \"id\": \"id1\", \"field\": \"field1\" }], \"paging\": { \"prev\": \"link1\", } }";
    string s2 = "{ \"data\": [{ \"id\": \"id2\", \"field\": \"field2\" }], \"paging\": { \"prev\": \"link2\", } }";
    
    var d1 = JsonConvert.DeserializeObject<Container>(s1);
    var d2 = JsonConvert.DeserializeObject<Container>(s2);
    
    d1.data.AddRange(d2.data);
    
    var result = JsonConvert.SerializeObject(d1);
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2011-03-19
      • 1970-01-01
      • 2020-03-17
      • 2017-11-17
      • 2013-05-07
      • 2017-01-31
      • 2018-09-13
      • 1970-01-01
      相关资源
      最近更新 更多