比较两个JavaScript对象数组并合并数据

时间:2020-05-04 14:41:26

标签: javascript

我在比较键上的两个对象数组时遇到了麻烦。

我想比较,当键匹配时减去值,当不在目标数组中时显示负值。最后,我想在最终数组中包含所有目标对象(如果键不匹配)。

一个示例将保存1000个单词:

const initial = [{id: 1, value: 47}, {id: 2, value: 20}, {id: 7, value: 13}];
const target = [{id: 1, value: 150}, {id: 3, value: 70}, {id: 40, value: 477}];
        
//Desired output
// [{id: 1, value: 103}, {id: 2, value: -20}, {id: 7, value: -13}, {id: 3, value: 70}, {id: 40, value: 477}];
        
let comparator = [];
        
initial.map(initia => {
   let hasSame = target.find(targ => {
        return initia.id === targ.id
      });
            
     if(hasSame){
        initia.value -= hasSame.value
     } else{
        initia.value = -initia.value
    }
});

console.log(initial);

除了不知道如何正确合并目标值外,我几乎得到了想要的结果。是否可以合并这些值而无需再次遍历目标数组?还是可以在find内执行此操作?

我想获得建议,以做到尽可能干净

谢谢!

2 个答案:

答案 0 :(得分:2)

您可以使用Map并收集具有所需求和因子的id

结果将键/值作为新属性。

var add = (map, factor) => ({ id, value }) => map.set(id, map.has(id)
        ? map.get(id) - value * factor
        : value * factor
    ),
    initial = [ {id: 1, value: 47 }, { id: 2, value: 20 }, { id: 7, value: 13 }],
    target = [{ id: 1, value: 150 }, { id: 3, value: 70 }, { id: 40, value: 477 }],
    map = new Map,
    result;
    
initial.forEach(add(map, -1));
target.forEach(add(map, 1));
result = Array.from(map, ([id, value]) => ({ id, value }));

console.log(result);
.as-console-wrapper { max-height: 100% !important; top: 0; }

答案 1 :(得分:1)

如果要避免在循环内部进行嵌套查找,则可以将两个数组简化为Set。它们不允许重复的键,因此您将确保为每个提供的ID提供一个值。

const valueSet = [...initial, ...target].reduce((total, obj) => {
  total[obj.id] = !total[obj.id] 
    ? -obj.value
    : total[obj.id] -= obj.value
  return total;
}, {});

const result = Object.keys(valueSet).map(key => ({ id: key, value: valueSet[key]}))
console.log(result);

然后,您将映射回结果以构建预期的数组。