如何使用 Javascript 获取包含重复值的数组交集

How can i get arrays intersection include duplicate values using Javascript

我需要类似 lodash.intersectionWith 的内容,但我还需要结果数组中的重复值。

示例:

var objects = [{ 'x': 1, 'y': 2 }, { 'x': 2, 'y': 1 }, { 'x': 1, 'y': 2 }];
var others = [{ 'x': 1, 'y': 1 }, { 'x': 1, 'y': 2 }];
_.intersectionWith(objects, others, _.isEqual);

预期结果:

[{ 'x': 1, 'y': 2 },{ 'x': 1, 'y': 2 }]

提前致谢!

使用 reduce 验证第一个 array 中的每个 object,然后检查第二个 array 中是否存在 object。如果它存在,reducepush 那个 object 变成它的 array

reduce 函数将自动 return 那个新的 array

var objects = [{ 'x': 1, 'y': 2 }, { 'x': 2, 'y': 1 }, { 'x': 1, 'y': 2 }];
var others = [{ 'x': 1, 'y': 1 }, { 'x': 1, 'y': 2 }];

var res = objects.reduce(
  function(arr, obj){
    if(containsObject(obj, others))
      arr.push(obj);
    return arr;
  }, 
  []
);


function containsObject(obj, list) {
    var x;
    var ret = false;
  
    list.forEach(function(s){
      ret = JSON.stringify(s) == JSON.stringify(obj);
    });

    return ret;
}

console.log(res);

您可以通过过滤掉第一个数组中与第二个数组中的项不匹配的项来找到交集。第一个数组中的任何重复项都将保留。

var intersectwith = function(f,xs,ys){
    return xs.filter(function(x){
        return ys.some(function(y){
            return f(x,y);
        });
    });
};

var equals = function(x,y){
    return x === y;
};
console.log(intersectwith(equals, [1,2,3], [1,1,2,2,4]));
console.log(intersectwith(equals, [1,1,2,2,4], [1,2,3]));

或者,更易读,使用 ES6:

const intersectwith = (f,xs,ys) => xs.filter(x => ys.some(y => f(x,y)));
const equals = (x,y) => x === y;

console.log(intersectwith(equals, [1,2,3], [1,1,2,2,4]));
console.log(intersectwith(equals, [1,1,2,2,4], [1,2,3]));

_.isEqual 代替 equals 比较对象:jsfiddle.

有用的文档:
Array.prototype.filter
Array.prototype.some

你可以利用differenceWith() to get the difference between the source object and the symmetric difference of the source object and the others object using xorWith()

var result = _.differenceWith(
  objects, 
  _.xorWith(objects, others, _.isEqual), 
  _.isEqual
);

var objects = [{ 'x': 1, 'y': 2 }, { 'x': 2, 'y': 1 }, { 'x': 1, 'y': 2 }];
var others = [{ 'x': 1, 'y': 1 }, { 'x': 1, 'y': 2 }];


var intersection = _.intersectionWith(objects, others, _.isEqual);

var result = _.differenceWith(
  objects, 
  _.xorWith(objects, others, _.isEqual), 
  _.isEqual
);

document.write('<pre>' + JSON.stringify(result, 0, 4) + '</pre>');
<script src="https://cdnjs.cloudflare.com/ajax/libs/lodash.js/4.13.1/lodash.js"></script>