比较两个数组并返回差异

67

如何快速/最好地比较两个数组并返回它们之间的差异?就像PHP中的array_diff一样。是否有一个简单的函数可以实现,还是我需要通过each()foreach循环来创建一个函数?


你可能想要查看这个来自Stack Overflow的过去问题的答案。它基于数组原型进行构建。 - Richard Neil Ilagan
嗨,伙计,我认为你可以使用inArray函数并填充两个数组之间的差异;我已经为你粘贴了一个可工作的演示,希望能对你有所帮助 B-) - Tats_innit
返回已翻译的文本:重复的https://dev59.com/aXM_5IYBdhLWcg3w3nbz(即使在那里已经链接到其他地方) - cregox
10个回答

147

我知道这是一个老问题,但是我想分享一下这个小技巧。

var diff = $(old_array).not(new_array).get();

diff 现在包含了 old_array 中不在 new_array 中的内容


2
我喜欢简短的内容,就像这个一样。我将它与 $.merge() 一起使用,以特定顺序连接差异... - kingkode
1
如果数组包含对象,这个方法能用吗?我试图比较两个数组中的对象。 - Batman
2
这是一个场景。对于$(['h','h','h','h','h']).not($(["a", "a", "a"]))这个数组,它运行得很好,但是对于像$(['h','h','h','h','h']).not($(["a", "a", "a", "h"]))(注意数组中的最后一个"h")这样的数组,它返回一个空数组。差异没有被返回。因此,它是有问题的。 - Vishnu Narang
2
@VishnuNarang 我认为你在这里误解了一些事情。首先是数组差异的工作原理,其次是没有阅读OP所问的实际问题。让我们先处理第一个误解。在您的第二个示例中返回一个空数组是完全正确的结果。它返回了第一个数组中不在第二个数组中的内容(即什么也没有)。这就是第一个数组和第二个数组之间的“差异”。其次,OP要求一个类似于PHP的(array_diff)的jQuery函数。这就是它!通过PHP的array_diff()函数运行您的示例也会产生一个空数组。 - superphonic
@VishnuNarang 我非常有信心,PHP的array_diff()函数没有问题。 - superphonic
显示剩余7条评论

71

演示 http://jsfiddle.net/u9xES/

好的链接(JQuery文档):http://docs.jquery.com/Main_Page{你可以在这里搜索或阅读API}

如果你想用JQuery实现这个功能,希望这对你有所帮助。

最后的提示框会显示两个数组之间不同的元素所组成的数组。

如果我漏掉了什么,请告诉我,谢谢!

代码

var array1 = [1, 2, 3, 4, 5, 6];
var array2 = [1, 2, 3, 4, 5, 6, 7, 8, 9];
var difference = [];

jQuery.grep(array2, function(el) {
        if (jQuery.inArray(el, array1) == -1) difference.push(el);
});

alert(" the difference is " + difference);​ // Changed variable name 

8
这个方法很棒,但应考虑当array2的长度小于array1的情况。 - Jimmy Huang
15
更加简洁的写法是:difference = $.grep(a1, function(x) { return !$.inArray(x, a2); });。这样可以得到a1数组中所有不在a2中出现的元素集合,而不需要使用小于零的比较运算符。 - Jocelyn delalande
2
很好的回答。但是我想指出你使用了 .grep.each 一样;应该是 difference = $.grep(array2, function(el) { return $.inArray( el, array1 ) == -1; }) - PeterKA
1
老兄,你太棒了 :) 我卡了大约两天,你带我走出了困境。 - Hassan Murtaza
1
@Jocelyndelalande的评论Fiddle链接:http://jsfiddle.net/cqsLvxod/ - Shivam Sharma
显示剩余3条评论

9

将下划线用作:

_.difference(array1,array2)

1
这并没有提供问题的答案。如果您想对作者进行批评或请求澄清,请在他们的帖子下留言。 - AlSki
2
@AlSki 它回答了所提出的问题!比较这两个数组并返回它们之间的差异。 - anurag_29
1
@anurag_29 这个问题是如何使用jQuery解决,而不是Underscore。 - reergymerej
1
@AlSki 当答案在多年后发布时,我认为使用不同的库来回答问题是合适的,因为这是问题的一个可能的答案 - 不知道原帖作者或其他多年后访问该问题的人是否知道该库。 - Dan Nissenbaum

3
var arrayDiff = function (firstArr, secondArr) {
    var i, o = [], fLen = firstArr.length, sLen = secondArr.length, len;


    if (fLen > sLen) {
        len = sLen;
    } else if (fLen < sLen) {
        len = fLen;
    } else {
        len = sLen;
    }
    for (i=0; i < len; i++) {
        if (firstArr[i] !== secondArr[i]) {
            o.push({idx: i, elem1: firstArr[i], elem2: secondArr[i]});  //idx: array index
        }
    }

    if (fLen > sLen) {  // first > second
        for (i=sLen; i< fLen; i++) {
            o.push({idx: i, 0: firstArr[i], 1: undefined});
        }
    } else if (fLen < sLen) {
        for (i=fLen; i< sLen; i++) {
            o.push({idx: i, 0: undefined, 1: secondArr[i]});
        }
    }    

    return o;
};

3
/** SUBTRACT ARRAYS **/
function subtractarrays(array1, array2){
    var difference = [];
    for( var i = 0; i < array1.length; i++ ) {
        if( $.inArray( array1[i], array2 ) == -1 ) {
                    difference.push(array1[i]);
        }
    }

    return difference;
}   

您可以在代码的任何地方调用该函数。

var I_like    = ["love", "sex", "food"];
var she_likes = ["love", "food"];

alert( "what I like and she does't like is: " + subtractarrays( I_like, she_likes ) ); //returns "Naughty"!

这种方法在所有情况下都有效,避免了上述方法中的问题。希望这能有所帮助!

3

简单来说,可以这么说:

最初的回答:

const diff = (a, b) => b.filter((i) => a.indexOf(i) === -1);

result:

diff(['a', 'b'], ['a', 'b', 'c', 'd']);

["c", "d"]

2
如果您也想比较答案的顺序,可以将答案扩展为类似以下内容:
Array.prototype.compareTo = function (array2){
    var array1 = this;
    var difference = [];
    $.grep(array2, function(el) {
        if ($.inArray(el, array1) == -1) difference.push(el);
    });
    if( difference.length === 0 ){
        var $i = 0;
        while($i < array1.length){
            if(array1[$i] !== array2[$i]){
                return false;
            }
            $i++;
        }
        return true;
    }
    return false;
}

2
以这种方式,您不需要担心第一个数组是否比第二个小。
var arr1 = [1, 2, 3, 4, 5, 6,10],
    arr2 = [1, 2, 3, 4, 5, 6, 7, 8, 9];

function array_diff(array1, array2){
    var difference = $.grep(array1, function(el) { return $.inArray(el,array2) < 0});
    return difference.concat($.grep(array2, function(el) { return $.inArray(el,array1) < 0}));;
}

console.log(array_diff(arr1, arr2));

1

这样的数组操作并不是jQuery的强项。您应该考虑使用一个像Underscorejs这样的库,尤其是差异函数。


1
这应该适用于未排序的数组、双精度值和不同的顺序和长度,同时给出来自array1、array2或两者的过滤值。
function arrayDiff(arr1, arr2) {
    var diff = {};

    diff.arr1 = arr1.filter(function(value) {
        if (arr2.indexOf(value) === -1) {
            return value;
        }
    });

    diff.arr2 = arr2.filter(function(value) {
        if (arr1.indexOf(value) === -1) {
            return value;
        }
    });

    diff.concat = diff.arr1.concat(diff.arr2);

    return diff;
};

var firstArray = [1,2,3,4];
var secondArray = [4,6,1,4];

console.log( arrayDiff(firstArray, secondArray) );
console.log( arrayDiff(firstArray, secondArray).arr1 );
// => [ 2, 3 ]
console.log( arrayDiff(firstArray, secondArray).concat );
// => [ 2, 3, 6 ]

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接