合并两个对象数组,并在键值上覆盖

时间:2018-04-10 10:59:31

标签: javascript arrays json

我正在尝试合并来自对象数组的json中的数据。我在这里使用了下划线解决方案merge two json object based on key value in javascript,但事实证明它并没有覆盖我现在需要做的现有项目。

结果应该是数组1的所有项目的顺序相同,由数组2覆盖,其中id = id。数组1中不存在于数组1中的项应该被推送到结果的末尾。

第一个阵列:

[
 {id: 8, category: "A"}
 {id: 2, category: "D"}
 {id: 5, category: "C"}
 {id: 9, category: "B"}
]

第二阵列:

[
 {id: 1, category: "X"}
 {id: 2, category: "Y"}
]

预期结果:

[
 {id: 8, category: "A"}
 {id: 2, category: "Y"}
 {id: 5, category: "C"}
 {id: 9, category: "B"}
 {id: 1, category: "X"}
]

7 个答案:

答案 0 :(得分:3)

使用filterfindconcat

鉴于此

var arr1 = [
 {id: 8, category: "A"},
 {id: 2, category: "D"},
 {id: 5, category: "C"},
 {id: 9, category: "B"}
];
var arr2 = [
 {id: 12, category: "X"},
 {id: 2, category: "Y"}
];

如果订单不重要

var output = arr2.concat( 
        arr1.filter( s => 
            !arr2.find( t => t.id == s.id ) 
        )//end filter 
);//end concat

<强>演示

var arr1 = [{
    id: 8,
    category: "A"
  },
  {
    id: 2,
    category: "D"
  },
  {
    id: 5,
    category: "C"
  },
  {
    id: 9,
    category: "B"
  }
];
var arr2 = [{
    id: 12,
    category: "X"
  },
  {
    id: 2,
    category: "Y"
  }
];

var output = arr2.concat(
  arr1.filter(s =>
    !arr2.find(t => t.id == s.id)
  ) //end filter 
); //end concat

console.log(output);

如果订单很重要

var output = arr1.map( 
       s => arr2.find( 
           t => t.id == s.id ) || s 
).concat( //end map of arr1
      arr2.filter( 
           s => !arr1.find( t => t.id == s.id ) 
      ) //end filter
);//end concat

<强>演示

var arr1 = [{
    id: 8,
    category: "A"
  },
  {
    id: 2,
    category: "D"
  },
  {
    id: 5,
    category: "C"
  },
  {
    id: 9,
    category: "B"
  }
];
var arr2 = [{
    id: 12,
    category: "X"
  },
  {
    id: 2,
    category: "Y"
  }
];

var output = arr1.map(
  s => arr2.find(
    t => t.id == s.id) || s
).concat( //end map of arr1
  arr2.filter(
    s => !arr1.find(t => t.id == s.id)
  ) //end filter
); //end concat


console.log(output);

答案 1 :(得分:0)

您可以使用Map作为闭包,并存储此id的结果数组的索引。

&#13;
&#13;
var first = [{ id: 8, category: "A" }, { id: 2, category: "D" }, { id: 5, category: "C" }, { id: 9, category: "B" }],
    second = [{ id: 12, category: "X" }, { id: 2, category: "Y" }],
    result = [first, second].reduce((m => (r, a) => {
        a.forEach(o => {
            if (m.has(o.id)) {
                r[m.get(o.id)] = o;
                return;
            }
            m.set(o.id, r.push(o) - 1);
        });        
        return r;
    })(new Map), []);
    
console.log(result);
&#13;
&#13;
&#13;

答案 2 :(得分:0)

您可以在secondArray上设置循环,并针对id id firstArray的对象检查每个对象的var firstArray = [ {id: 8, category: "A"}, {id: 2, category: "D"}, {id: 5, category: "C"}, {id: 9, category: "B"} ]; var secondArray = [ {id: 12, category: "X"}, {id: 2, category: "Y"} ]; secondArray.forEach((obj)=>{ var match = false; for(var i=0; i<firstArray.length; i++){ if(firstArray[i].id === obj.id){ match = true; firstArray[i] = obj; break; } } if(!match){ firstArray.push(obj); } }); console.log(firstArray);值。如果找到匹配,则只需替换对象,否则按下对象:

external lib

答案 3 :(得分:0)

您可以使用forEach来遍历second数组。对于第一个数组中具有相同id的每个对象,更新category否则推入新数组。

const first = [{id: 8, category: "A"},{id: 2, category: "D"},{id: 5, category: "C"},{id: 9, category: "B"}],
      second = [{id: 12, category: "X"},{id: 2, category: "Y"}],
      merged = [...first]; 
second.forEach(o => {
  let obj = first.find(({id,category}) => id === o.id);
  obj ? obj.category = o.category : merged.push({...o});
});
console.log(merged);

答案 4 :(得分:0)

我认为 reduce 更好

first.reduce((res, item) => res.filter(i => i.id !== item.id).concat(item), second);

答案 5 :(得分:0)

使用下划线我设法得到了这个答案我自己的问题。它可能不是最有效的

const newarr = _.map(arr1, obj1 => {
  const r = _.find(arr2, obj2 => {
    return obj1[match] === obj2[match]
  })
  if (typeof r === 'undefined') {
    return obj1
  } else {
    return r
  }
})
_.each(arr2, obj => {
  if (_.indexOf(arr1, _.findWhere(arr1, {id: obj.id})) === -1) { 
   newarr.push(obj) 
  }
})

答案 6 :(得分:0)

这应该有效:

const newArr = second.reduce((res, item) => res.filter(i => i.id !== item.id).concat(item), first);