如何获得两个数组之间的差异,但保留重复对象

时间:2017-04-04 16:59:39

标签: javascript arrays node.js lodash

假设您有两个包含对象的数组,数组1 数组2 。我遇到的问题是找到两个数组之间的精确差异,这两个数组可能包含看似相等的元素。在这个例子中,我评论了每个数组中的特定对象。

考虑到购物车带有重复商品,但您只能兑换一件商品。因此//number 4是重复项目之一,但您仍然需要数组3

ARRAY 1

[
  { // number 1
    item_id: 4,
    total_price: 2.71
  },
  { // number 2
    item_id: 2,
    total_price: 3.71
  },
  { // number 3
    item_id: 4,
    total_price: 1.71
  },
  { // number 4
    item_id: 4,
    total_price: 2.71
  }
]

ARRAY 2

[
  { // number 1
    item_id: 4,
    total_price: 2.71
  }
]

如何找到这两个数组之间的区别,数组3 ?并且最好是在每个对象上都有一个唯一的键来比较容易吗?在javascript / node中执行此操作,主要使用lodash。

ARRAY 3

[
  { // number 2
    item_id: 2,
    total_price: 3.71
  },
  { // number 3
    item_id: 4,
    total_price: 1.71
  },
  { // number 4
    item_id: 4,
    total_price: 2.71
  }
]

7 个答案:

答案 0 :(得分:2)

以下是使用lodash#differenceWith的解决方案。

function difference(arr1, arr2) {
  var found = {};
  return _.differenceWith(arr1, arr2, function(x, y) {
    var isDiff = _.isEqual(x, y) && !found[x.id];
    found[x.id] = true;
    return isDiff;
  });
}



var array1 = [
  { // number 1
    item_id: 4,
    total_price: 2.71
  },
  { // number 2
    item_id: 2,
    total_price: 3.71
  },
  { // number 3
    item_id: 4,
    total_price: 1.71
  },
  { // number 4
    item_id: 4,
    total_price: 2.71
  }
];

var array2 = [
  { // number 1
    item_id: 4,
    total_price: 2.71
  }
];

function difference(arr1, arr2) {
  var found = {};
  return _.differenceWith(arr1, arr2, function(x, y) {
    var isDiff = _.isEqual(x, y) && !found[x.id];
    found[x.id] = true;
    return isDiff;
  });
}

console.log(difference(array1, array2));

body > div { min-height: 100%; top: 0 }

<script src="https://cdnjs.cloudflare.com/ajax/libs/lodash.js/4.17.4/lodash.js"></script>
&#13;
&#13;
&#13;

答案 1 :(得分:1)

你可以使用lodash:

这样做
array2.forEach(el => {
  let index = _.findIndex(array1, e => e.item_id === el.item_id);
  if (index >= 0) {
    array1.splice(index, 1);
  }
});

现在,您的array1将删除正确的值。如果您想保留原始array1,请先将其复制并处理副本:

let array3 = _.clone(array1);
array2.forEach(el => {
  let index = _.findIndex(array3, e => e.item_id === el.item_id);
  if (index >= 0) {
    array3.splice(index, 1);
  }
});

现在您的结果为array3

答案 2 :(得分:1)

所以基本上你想从Array1中减去Array2?

有点难看,但它有效:

for(var i = 0; i < arrayA.length; i++) {
    var arrAElement = arrayA[i];

    arrayC.push(arrAElement);

    for(var j = 0; j < arrayB.length; j++) {
        var arrBElement = arrayB[j];

        if(arrAElement.item_id == arrBElement.item_id && 
           arrAElement.total_price == arrBElement.total_price) {
            arrayB.splice(j,1);
            arrayC.pop();
            break;
        }
    }
}

工作演示: https://jsfiddle.net/a0180jdf/

答案 3 :(得分:0)

如果项目存在于Array2中,您可以遍历Array1并检查每个条目,如果没有将它放在Array3中。

代码如下:

for (var elt : array1) {
   var eltFound = false;
   var i = 0;

   // Loops in array2 to find element
   while (!eltFound && i < array2.length) {
      if (array2[i] == elt) { // maybe here do the check with item_id <-> elt[0]
         eltFound = true;
      }
   }

   if (!eltFound) {
      array3.push(elt);
   }
}

答案 4 :(得分:0)

仅在JS中,我宁愿使用slice并逐个踢项目:

for(var i = 0 ; i < array1.length ; i++) {
  for(var j = 0 ; j < array2.length ; j++) {
    if(array1[i].item_id == array2[j].item_id && array1[i].total_price == array2[j].total_price) {
      array1.splice(i,1);
      array2.splice(j,1);
      i--;
      j--;
      break;
    }
  }
}
console.log(array1);

array1现在包含差异的值。我刚用你的数据测试过它。

答案 5 :(得分:0)

您可以执行以下操作;

function removeDupes(a){
  var hash = a.reduce(function(h,o){
                        var k = Object.keys(o).reduce((p,c) => "" + o[p] + o[c]);
                        h[k] || (h[k] = o);
                        return h;
                      },{});
  return Object.keys(hash)
               .map(k => hash[k]);
}

var data = [
  { // number 1
    item_id: 4,
    total_price: 2.71
  },
  { // number 2
    item_id: 2,
    total_price: 3.71
  },
  { // number 3
    item_id: 4,
    total_price: 1.71
  },
  { // number 4
    item_id: 4,
    total_price: 2.71
  }
],
 result = removeDupes(data);
 console.log(result);

答案 6 :(得分:0)

如果您想保留原始arr1值,可以使用_.cloneDeep(arr1)

var arr1 = [{ // number 1
    item_id: 4,
    total_price: 2.71
}, { // number 2
    item_id: 2,
    total_price: 3.71
}, { // number 3
    item_id: 4,
    total_price: 1.71
}, { // number 4
    item_id: 4,
    total_price: 2.71
}];

let arr2 = [{ // number 1
    item_id: 4,
    total_price: 2.71
}];

// Loops through `arr2` and compare each element with `arr1`
arr2.forEach(el2 => arr1.every((el1, index) =>
    // Compare `el2` with every `el1` in `arr1`
    // If `el2` === `el1`, return true to continue every loop
    // Otherwise, splice it out from the curren `index` and return false
    // to stop the every loop.
    el1.item_id !== el2.item_id || el1.total_price !== el2.total_price ? 
    true : arr1.splice(index, 1) && false
));

console.log(arr1);