比较深处的两个数组对象,并使用JavaScript将不同的值存储在第三个数组中

时间:2018-09-24 08:04:05

标签: javascript

我有这样的数组;

$scope.result1 = [
    {id:1, name:'pppp', type:'user', username:'345'},
    {id:2, name:'John', type:'admin', username:'johnny2'},
    {id:3, name:'Peter', type:'user', username:'pete'},
];

$scope.result2 = [
    {id:1, name:'Seema', type:'admin', username:'123'},
    {id:2, name:'John', type:'admin', username:'johnny2'},
    {id:3, name:'Peter123', type:'user', username:'pete'},
];

我想将result2与result1进行比较,并仅在第三数组中存储不同的值。 预期结果是;

$scope.result = [
        { name:'Seema', type:'admin', username:'123'},
        {name:'Peter123'},
    ];

预先感谢

4 个答案:

答案 0 :(得分:2)

您可以为具有相同id的对象制作地图,然后检查属性是否发生更改,并仅在新数组中返回更改后的属性。

var $scope = {
        result1: [{ id:1, name:'pppp', type:'user', username:'345' }, { id:2, name:'John', type:'admin', username:'johnny2' }, { id:3, name:'Peter', type:'user', username:'pete' }],
        result2: [{ id:1, name:'Seema', type:'admin', username:'123' }, { id:2, name:'John', type:'admin', username:'johnny2' }, { id:3, name:'Peter123', type:'user', username:'pete' }]
    },
    map = new Map($scope.result1.map(o => [o.id, o]));

$scope.result = $scope.result2.reduce((r, o) => {
    var object = map.get(o.id) || {},
        temp = Object.entries(o).filter(([k, v]) => object[k] !== v);

    if (temp.length) {
        r.push(Object.assign(...temp.map(([k, v]) => ({ [k]: v }))));
    }
    return r;
}, []);

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

答案 1 :(得分:1)

如果像我认为您需要查找更新的值,则可以按照以下步骤进行操作:

var $scope = {};

$scope.result1 = [
    {id:1, name:'pppp', type:'user', username:'345'},
    {id:2, name:'John', type:'admin', username:'johnny2'},
    {id:3, name:'Peter', type:'user', username:'pete'},
];

$scope.result2 = [
    {id:1, name:'Seema', type:'admin', username:'123'},
    {id:2, name:'John', type:'admin', username:'johnny2'},
    {id:3, name:'Peter123', type:'user', username:'pete'},
];

$scope.diffResult = []

for (let i=0; i<$scope.result1.length; i++){
    const o1 = $scope.result1[i];
    const o2 = $scope.result2[i];
    const diff = {};

    Object.getOwnPropertyNames(o1).forEach(p => {
        if (o1[p] !== o2[p]) {
            diff[p] = o2[p];
        }
    })

    if (Object.getOwnPropertyNames(diff).length > 0){
        $scope.diffResult.push(diff);
    }
}

console.log($scope.diffResult);

另一种可能的方法是使用经过更好测试的模块,例如deep-diff

答案 2 :(得分:1)

对于第二个结果中的每个对象,您可以找出哪些值不同,然后使用这些值。

const result1 = [
    {id:1, name:'pppp', type:'user', username:'345'},
    {id:2, name:'John', type:'admin', username:'johnny2'},
    {id:3, name:'Peter', type:'user', username:'pete'},
];

const result2 = [
    {id:1, name:'Seema', type:'admin', username:'123'},
    {id:2, name:'John', type:'admin', username:'johnny2'},
    {id:3, name:'Peter123', type:'user', username:'pete'},
];

const getAllKeys = objects => [
  ...(new Set (objects.reduce((prev, curr) => [
    ...prev,
    ...Object.keys(curr)
  ], [])))
];

const getObjectDifferences = (objectOne, objectTwo) => 
  getAllKeys([objectOne, objectTwo])
    .map(key => objectOne[key] !== objectTwo[key] ? key : false)
    .filter(v => !!v)
    .reduce((prev, curr) => ({
      ...prev,
      [curr]: objectTwo[curr],
    }), {})

const getDifferences = (listOne, listTwo) => listTwo
  .map(item => getObjectDifferences(
    listOne.filter(x => x.id === item.id)[0],
    item
  )).filter(item => Object.keys(item).length > 0)
  
console.dir(getDifferences(result1, result2))

答案 3 :(得分:1)

假设:如果result1中有id:x,那么result2中也将有id:x。

首先,在result2上使用map来确定差异。

然后,在新数组上使用过滤器,以清除空对象。

var result1 = [
    {id:1, name:'pppp', type:'user', username:'345'},
    {id:2, name:'John', type:'admin', username:'johnny2'},
    {id:3, name:'Peter', type:'user', username:'pete'},
];

var result2 = [
    {id:1, name:'Seema', type:'admin', username:'123'},
    {id:2, name:'John', type:'admin', username:'johnny2'},
    {id:3, name:'Peter123', type:'user', username:'pete'},
];

var result = result2.map(entry2 => {
    var ret = {};
    result1.forEach(entry1 => {
    if (entry2.id === entry1.id){
        if(entry2.name !== entry1.name){
        ret['name'] = entry2.name;
      }
      if (entry2.type !== entry1.type){
        ret['type'] = entry2.type;
      }
      if (entry2.username !== entry1.username){
        ret['username'] = entry2.username;
      }
    }
  });
  return ret;
});

result = result.filter(entry => Object.keys(entry).length > 0);

console.log(result);