Javascript 如何使用唯一键合并2个JSON,并使用另一个子唯一键深度合并嵌套的数组对象

Javascript 如何使用唯一键合并2个JSON,并使用另一个子唯一键深度合并嵌套的数组对象,javascript,node.js,arrays,json,merge,Javascript,Node.js,Arrays,Json,Merge,这是中所述解决方案的延续,只是输入JSON具有更深层次的嵌套数组对象: json1 [ { "id": 1, "name": "aaa", "addresses": [ { "type": "office", "city": "office city" }

这是中所述解决方案的延续,只是输入JSON具有更深层次的嵌套数组对象:

json1

[
  {
    "id": 1,
    "name": "aaa",
    "addresses": [
      {
        "type": "office",
        "city": "office city"
      },
      {
        "type": "home1",
        "city": "home1 city"
      }
    ]
  },
  {
    "id": 2,
    "name": "bbb",
    "addresses": [
      {
        "type": "office",
        "city": "office city"
      },
      {
        "type": "home1",
        "city": "home1 city"
      }
    ]
  }
]
json2

[
  {
    "id": 1,
    "name": "aaa1",
    "addresses": [
      {
        "type": "home1",
        "city": "home1 new city"
      },
      {
        "type": "home2",
        "city": "home2 city"
      }
    ]
  },
  {
    "id": 3,
    "name": "ccc",
    "addresses": [
      {
        "type": "home1",
        "city": "home1 city"
      },
      {
        "type": "home2",
        "city": "home2 city"
      }
    ]
  }
]
预期结果数组

[
  {
    "id": 1,
    "name": "aaa1",
    "addresses": [
      {
        "type": "office",
        "city": "office city"
      },            
      {
        "type": "home1",
        "city": "home1 new city"
      },
      {
        "type": "home2",
        "city": "home2 city"
      }
    ]
  },
  {
    "id": 2,
    "name": "bbb",
    "addresses": [
      {
        "type": "office",
        "city": "office city"
      },
      {
        "type": "home1",
        "city": "home1 city"
      }
    ]
  },          
  {
    "id": 3,
    "name": "ccc",
    "addresses": [
      {
        "type": "home1",
        "city": "home1 city"
      },
      {
        "type": "home2",
        "city": "home2 city"
      }
    ]
  }
]
当我遵循georg建议的解决方案时:

resultarray = _(json1).concat(json2).groupBy('id').map(_.spread(_.assign)).value();
“addresses”属性将被覆盖,而不是被合并。 如何使用唯一键合并2个JSON对象,并使用另一个子唯一键(“类型”)深度合并嵌套数组对象


也欢迎非洛达斯解决方案

下面是一个使用的通用答案

//const objectLib=require('object-lib');
const{Merge}=objectLib;
const json1=[{id:1,名称:“aaa”,地址:[{type:'office',city:'office city'},{type:'home1',city:'home1 city'}],{id:2,名称:“bbb”,地址:[{type:'office',city:'office city'},{type:'home1,city:'home1 city'}];
const json2=[{id:1,名称:'aaa1',地址:[{type:'home1',city:'home1 new city'},{type:'home2',city:'home2 city'}],{id:3,名称:'ccc',地址:[{type:'home1',city:'home1 city'},{type:'home2 city:'home2 city'}];
const merge1=合并({
“[*]”:“id”,
“[*]”。地址[*]”:“类型”
})
log(merge1(json1,json2));
//=>[{id:1,名称:'aaa1',地址:[{type:'office',city:'office city'},{type:'home1',city:'home1 new city'},{type:'home2',city:'home2 city'}]},{id:2,name:'bbb',地址:[{type:'office',city:'office city'},{type:'home1',city:'home1 city'}]},{id:3,name:'ccc',地址:[{type:'home1',city:'home1 city'},{type:'home2',city:'home2 city'}]}]
// -----------
常量d1={id:1,other:[{type:'a',meta:'X',prop1:true}];
constd2={id:1,other:[{type:'a',meta:'Y',prop2:false}]};
console.log(Merge()(d1,d2))
//=>{id:1,其他:[{type:'a',meta:'X',prop1:true},{type:'a',meta:'Y',prop2:false}]}
log(合并({'**]':'type'})(d1,d2))
//=>{id:1,other:[{type:'a',meta:'Y',prop1:true,prop2:false}]}
。作为控制台包装{最大高度:100%!重要;顶部:0}

这里有一种方法。它假设您只想合并地址,并且其他属性保持不变。合并所有数组的通用工具可能会涉及更多内容,并且不会像这里那样容易地按类型选择正确的地址。如果您想要这样的工具,我没有使用过,但我可以最近在另一个答案中,有一个叫w

以下是我的实现:

const last=xs=>
xs[xs.length-1]
常量组=(fn)=>(xs)=>
Object.values(xs.reduce(
(a,x)=>((a[fn(x)]=[…(a[fn(x)]| |[]),x]),a),
{}
))
常量合并地址=(as)=>
as.reduce({addresses:a1,…rest1},{addresses:a2,…rest2})=>({
…rest1,
…rest2,
地址:组(a=>a.type)([…a1,…a2])。平面图(最后一个)
}))
const combine=(xs,ys)=>
组(x=>x.id)([…xs,…ys]).map(合并地址)
const xs=[{id:1,名称:“aaa”,地址:[{type:“office”,city:“office city”},{type:“home1”,city:“home1 city”},{id:2,名称:“bbb”,地址:[{type:“office”,city:“office city”},{type:“home1”,city:“home1 city”}]
const ys=[{id:1,名称:“aaa1”,地址:[{type:“home1”,city:“home1 new city”},{type:“home2”,city:“home2 city”},{id:3,名称:“ccc”,地址:[{type:“home1”,city:“home1 city”},{type:“home2”,city:“home2 city”}]
console.log(combine(xs,ys))

。作为控制台包装{max height:100%!重要;top:0}
我有一个有效的解决方案,但需要清理。请继续关注(希望在接下来的24小时内完成)哦,哇!这是个好消息!感谢你的帮助!非常有趣的问题,我喜欢精心设计答案。不客气。因为你是新来的,请不要忘记标记接受的答案,这对解决问题最有帮助。看看接受答案是如何工作的?很抱歉听到你的手臂!希望你快点好起来!检查“我如何接受答案,规则是什么?"谢谢,@vincent为我们提供了一个有趣的问题。不用担心!你会如何通用/动态地解决这个问题?即不同级别的数组需要由不同的字段合并?@vincent:很难想象一个好的API,更不用说实现了。我还没有真正看过你的,但我会的尽快这样做,也许在周末看一个通用概念。我刚刚将我的答案通用化。绝对不是琐碎的,但在我看来它是干净的。@ScottSauyet我们如何使这个解决方案通用化?数据数组名称和唯一键是动态的。新的库看起来很有用。我仍在考虑在通用数组处理
m中需要什么erge
函数。Ramda只是用另一个数组覆盖一个数组。但我可以想象至少三种其他策略:对象库中的函数/字段选择、简单的连接和合并每个索引处的值。如果我能想到四种,我肯定其他人会想出不同的方法。我对我考虑过的任何API都不满意d为了解决这个问题,我甚至采用了object scan有用的查询语法。我仍在思考,但不抱希望。我同意在合并中有更多选项可能对处理更多情况非常有用(应该很容易添加)。我喜欢当前字段的语法,但没有认真考虑,因此可能会有更好的语法。我认为API问题太多,无法用通用的方法解决。虽然我不记得当时的决定,但如果这就是为什么我们决定在Ramda中不使用它的原因,我也不会感到惊讶。这对我来说是一个很好的食物我喜欢你的输入,我认为api可以解决大多数情况。我可能会