使用 jQuery 比较两个 Javascript 对象数组

IT技术 javascript jquery arrays object compare
2021-01-26 23:49:24

我有两个 JavaScript 对象数组,我想比较它们是否相同。对象可能不会(并且很可能不会)在每个数组中的顺序相同。每个数组不应超过 10 个对象。我认为 jQuery 可能有一个优雅的解决方案来解决这个问题,但我在网上找不到太多东西。

我知道一个粗暴的嵌套$.each(array, function(){})解决方案可以工作,但是有没有我不知道的内置函数?

谢谢。

6个回答

有一个简单的方法...

$(arr1).not(arr2).length === 0 && $(arr2).not(arr1).length === 0

如果上述返回 true,则即使元素的顺序不同,两个数组也是相同的。

注意:当使用 JSON 对象时,这仅适用于 jquery 版本 < 3.0.0

@Alexxus,您需要两个比较,因为它not是一个过滤器函数,而不是一个相等函数。[1,2]试试看[1]在一个顺序中,您将获得[],而在另一个顺序中,您将获得[2]
2021-03-16 23:49:24
+1,但是当您将数组与包含相同属性的对象进行比较时,它等于真,f.ex [0,1] == {0:0,1:1,length=2}
2021-03-17 23:49:24
为什么$(arr1).not(arr2).length == 0不够?
2021-03-23 23:49:24
请注意,如果数组中有重复项,这将返回 true。所以类似:` [1,1,2,2,3,3] == [1,2,3]` 是正确的。
2021-04-04 23:49:24
not从 3.0.0-rc1 开始,jQuery不再适用于通用对象。github.com/jquery/jquery/issues/3147
2021-04-08 23:49:24

我今天也在找这个,发现:http : //www.breakpar.com/bkp/home.nsf/0/87256B280015193F87256BFB0077DFFD

不知道这是否是一个好的解决方案,尽管他们确实提到了一些性能方面的考虑。

我喜欢 jQuery 辅助方法的想法。@David 我宁愿看到你的比较方法像这样工作:

jQuery.compare(a, b)

我这样做没有意义:

$(a).compare(b)

其中 a 和 b 是数组。通常,当您使用$(something) 时,您会传递一个选择器字符串来处理 DOM 元素。

另外关于排序和“缓存”排序后的数组:

  • 我不认为在方法开始时排序一次而不是每次循环时排序都是“缓存”。每次调用 compare(b) 时,排序仍然会发生。这只是语义,但是......
  • for (var i = 0; t[i]; i++) { ...如果你的t数组在某处包含一个假值,这个循环会提前结束,所以$([1, 2, 3, 4]).compare( [1, false, 2, 3])返回true
  • 更重要的是阵列sort()方法排序数组的地方,这样做VAR B = t.sort() ......不创建原始数组的排序副本,它的排序阵列,并分配一个参考,以它在b我不认为比较方法应该有副作用。

看来我们需要做的是在处理数组之前复制它们。我能找到的关于如何以 jQuery 方式做到这一点的最佳答案就是 John Resig 在 SO!在 JavaScript 中深度克隆对象的最有效方法是什么? (请参阅他对对象克隆配方的数组版本的回答的评论)

在这种情况下,我认为它的代码是:

jQuery.extend({
    compare: function (arrayA, arrayB) {
        if (arrayA.length != arrayB.length) { return false; }
        // sort modifies original array
        // (which are passed by reference to our method!)
        // so clone the arrays before sorting
        var a = jQuery.extend(true, [], arrayA);
        var b = jQuery.extend(true, [], arrayB);
        a.sort(); 
        b.sort();
        for (var i = 0, l = a.length; i < l; i++) {
            if (a[i] !== b[i]) { 
                return false;
            }
        }
        return true;
    }
});

var a = [1, 2, 3];
var b = [2, 3, 4];
var c = [3, 4, 2];

jQuery.compare(a, b);
// false

jQuery.compare(b, c);
// true

// c is still unsorted [3, 4, 2]
确实当场。非常感谢。
2021-03-13 23:49:24
实际上,我可能会将此方法命名为“arrayCompare”而不是“compare”,因为这是它设计的唯一目的...
2021-03-19 23:49:24

我的方法完全不同 - 我使用 JSON.stringify 将两个集合展平,并使用普通字符串比较来检查相等性。

IE

var arr1 = [
             {Col: 'a', Val: 1}, 
             {Col: 'b', Val: 2}, 
             {Col: 'c', Val: 3}
           ];

var arr2 = [
             {Col: 'x', Val: 24}, 
             {Col: 'y', Val: 25}, 
             {Col: 'z', Val: 26}
           ];

if(JSON.stringify(arr1) == JSON.stringify(arr2)){
    alert('Collections are equal');
}else{
    alert('Collections are not equal');
}

注意:请注意,他的方法假设两个集合都以类似的方式排序,否则,它会给你一个错误的结果!

我需要一种简单的方法来比较单元测试中的数组,以确保两个数组的顺序相同。非常好,谢谢。
2021-03-15 23:49:24
谢谢你拯救了我的一天
2021-04-09 23:49:24

将两个数组都转换为字符串并进行比较

if (JSON.stringify(array1) == JSON.stringify(array2))
{
    // your code here
}
似乎很适合比较嵌套数组以及顺序很重要的情况。
2021-04-02 23:49:24

我发现这个讨论是因为我需要一种方法来深入比较数组和对象。使用这里的示例,我想出了以下内容(为了清楚起见,分为 3 种方法):

jQuery.extend({
    compare : function (a,b) {
        var obj_str = '[object Object]',
            arr_str = '[object Array]',
            a_type  = Object.prototype.toString.apply(a),
            b_type  = Object.prototype.toString.apply(b);

            if ( a_type !== b_type) { return false; }
            else if (a_type === obj_str) {
                return $.compareObject(a,b);
            }
            else if (a_type === arr_str) {
                return $.compareArray(a,b);
            }
            return (a === b);
        }
});

jQuery.extend({
    compareArray: function (arrayA, arrayB) {
        var a,b,i,a_type,b_type;
        // References to each other?
        if (arrayA === arrayB) { return true;}

        if (arrayA.length != arrayB.length) { return false; }
        // sort modifies original array
        // (which are passed by reference to our method!)
        // so clone the arrays before sorting
        a = jQuery.extend(true, [], arrayA);
        b = jQuery.extend(true, [], arrayB);
        a.sort(); 
        b.sort();
        for (i = 0, l = a.length; i < l; i+=1) {
            a_type = Object.prototype.toString.apply(a[i]);
            b_type = Object.prototype.toString.apply(b[i]);

            if (a_type !== b_type) {
                return false;
            }

            if ($.compare(a[i],b[i]) === false) {
                return false;
            }
        }
        return true;
    }
});

jQuery.extend({
    compareObject : function(objA,objB) {

        var i,a_type,b_type;

        // Compare if they are references to each other 
        if (objA === objB) { return true;}

        if (Object.keys(objA).length !== Object.keys(objB).length) { return false;}
        for (i in objA) {
            if (objA.hasOwnProperty(i)) {
                if (typeof objB[i] === 'undefined') {
                    return false;
                }
                else {
                    a_type = Object.prototype.toString.apply(objA[i]);
                    b_type = Object.prototype.toString.apply(objB[i]);

                    if (a_type !== b_type) {
                        return false; 
                    }
                }
            }
            if ($.compare(objA[i],objB[i]) === false){
                return false;
            }
        }
        return true;
    }
});

测试

var a={a : {a : 1, b: 2}},
    b={a : {a : 1, b: 2}},
    c={a : {a : 1, b: 3}},
    d=[1,2,3],
    e=[2,1,3];

console.debug('a and b = ' + $.compare(a,b)); // a and b = true
console.debug('b and b = ' + $.compare(b,b)); // b and b = true
console.debug('b and c = ' + $.compare(b,c)); // b and c = false
console.debug('c and d = ' + $.compare(c,d)); // c and d = false
console.debug('d and e = ' + $.compare(d,e)); // d and e = true