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

时间:2016-05-25 10:16:17

标签: javascript lodash

我需要像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 }]

提前致谢!

3 个答案:

答案 0 :(得分:3)

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



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

答案 1 :(得分:2)

您可以使用differenceWith()使用{{3}来区分来源object与来源objectothers对象的对称差异}。

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>

答案 2 :(得分:0)

使用reduce验证第一个object中的每个array,然后检查第二个object中是否存在array。如果存在,则reducepushobject加入其array

reduce函数会自动返回新的array

&#13;
&#13;
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);
&#13;
&#13;
&#13;