簡體   English   中英

使用jQuery比較兩個Javascript對象數組

[英]Using jQuery to compare two arrays of Javascript objects

我有兩個JavaScript對象數組,我想比較它們是否相同。 對象可能不會(並且很可能不會)在每個數組中具有相同的順序。 每個數組不應超過10個對象。 我認為jQuery可能有一個優雅的解決方案來解決這個問題,但我無法在網上找到太多。

我知道一個粗暴的嵌套$.each(array, function(){})解決方案可以工作,但有沒有我不知道的內置函數?

謝謝。

有一個簡單的方法......

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

如果以上返回true,則即使元素的順序不同,兩個數組也是相同的。

注意:這僅適用於使用JSON對象時jquery版本<3.0.0

我今天也在尋找這個並找到: http//www.breakingpar.com/bkp/home.nsf/0/87256B280015193F87256BFB0077DFFD

不知道這是否是一個很好的解決方案,盡管他們確實提到了一些考慮的性能因素。

我喜歡jQuery幫助器方法的想法。 @David我寧願看你的比較方法如下:

jQuery.compare(a, b)

我對自己沒有意義:

$(a).compare(b)

其中a和b是數組。 通常當你$(某事物)時,你會傳遞一個選擇器字符串來處理DOM元素。

還有關排序和“緩存”排序數組:

  • 我不認為在方法開始時排序一次而不是每次循環都是“緩存”。 每次調用compare(b)時仍會發生排序。 那只是語義,但......
  • for(var i = 0; t [i]; i ++){ ...如果你的t數組在某處包含一個假值,那么這個循環會提前結束,所以$([1,2,3,4])。compare( [1,false,2,3]返回true
  • 更重要的是陣列sort()方法排序到位陣列,這樣算下來變種B = t.sort()......不創建原始數組的排序副本,它按原始數組,並分配給一個參考它在b 我不認為比較方法應該有副作用。

我們需要做的是在處理數組之前復制數組。 對於如何以jQuery方式執行此操作,我能找到的最佳答案是John Resig在這里! 在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]

我的方法完全不同 - 我使用JSON.stringify將兩個集合展平,並使用普通的字符串比較來檢查是否相等。

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');
}

注意:請注意,他的方法假定兩個集合都以類似的方式排序,如果沒有,它會給你一個錯誤的結果!

將兩個數組轉換為字符串並進行比較

if (JSON.stringify(array1) == JSON.stringify(array2))
{
    // your code here
}

我找到了這個討論,因為我需要一種深入比較數組和對象的方法。 使用這里的示例,我想出了以下內容(為了清晰起見分為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

在我的情況下,比較數組只包含數字字符串 這個解決方案對我有用:

function are_arrs_equal(arr1, arr2){
    return arr1.sort().toString() === arr2.sort().toString()
}

我們來試試吧!

arr1 = [1, 2, 3, 'nik']
arr2 = ['nik', 3, 1, 2]
arr3 = [1, 2, 5]

console.log (are_arrs_equal(arr1, arr2)) //true
console.log (are_arrs_equal(arr1, arr3)) //false

Sudhakar R作為jQuery全局方法的優秀內容

/**
 * Compare two arrays if they are equal even if they have different order.
 *
 * @link https://stackoverflow.com/a/7726509
 */
jQuery.extend({
  /**
   * @param {array} a
   *   First array to compare.
   * @param {array} b
   *   Second array to compare.
   * @return {boolean}
   *   True if both arrays are equal, otherwise false.
   */
  arrayCompare: function (a, b) {
    return $(a).not(b).get().length === 0 && $(b).not(a).get().length === 0;
  }
});

我不認為有一個很好的“jQuery”方法可以做到這一點,但是如果你需要效率,可以通過某個鍵(一個唯一的對象字段)映射其中一個數組,然后通過循環遍歷另一個數組進行比較和你剛剛建立的地圖或關聯數組進行比較。

如果效率不是問題,只需將A中的每個對象與B中的每個對象進行比較。只要| A | 和| B | 很小,你應該沒事。

好吧,如果你只想比較數組的內容,那么有一個有用的jQuery函數$ .inArray()

var arr = [11, "String #1", 14, "String #2"];
var arr_true = ["String #1", 14, "String #2", 11]; // contents are the same as arr
var arr_false = ["String #1", 14, "String #2", 16]; // contents differ

function test(arr_1, arr_2) {
    var equal = arr_1.length == arr_2.length; // if array sizes mismatches, then we assume, that they are not equal
    if (equal) {
        $.each(arr_1, function (foo, val) {
            if (!equal) return false;
            if ($.inArray(val, arr_2) == -1) {
                equal = false;
            } else {
                equal = true;
            }
        });
    }
    return equal;
}

alert('Array contents are the same? ' + test(arr, arr_true)); //- returns true
alert('Array contents are the same? ' + test(arr, arr_false)); //- returns false

將數組更改為字符串並進行比較

var arr = [1,2,3], 
arr2 = [1,2,3]; 
console.log(arr.toString() === arr2.toString());

我在尋找與jQuery進行一些數組比較時也發現了這一點。 在我的情況下,我有字符串,我知道是數組:

var needle = 'apple orange';
var haystack = 'kiwi orange banana apple plum';

但我關心的是它是完全匹配還是只是部分匹配,所以我根據Sudhakar R的答案使用了類似下面的內容:

function compareStrings( needle, haystack ){
  var needleArr = needle.split(" "),
    haystackArr = haystack.split(" "),
    compare = $(haystackArr).not(needleArr).get().length;

  if( compare == 0 ){
    return 'all';
  } else if ( compare == haystackArr.length  ) {
    return 'none';
  } else {
    return 'partial';
  }
}

如果重復事項使得[1, 1, 2]不應該等於[2, 1]但應該等於[1, 2, 1] ,那么這里是一個引用計數解決方案:

  const arrayContentsEqual = (arrayA, arrayB) => {
    if (arrayA.length !== arrayB.length) {
      return false}

    const refCount = (function() {
      const refCountMap = {};
      const refCountFn = (elt, count) => {
          refCountMap[elt] = (refCountMap[elt] || 0) + count}
      refCountFn.isZero = () => {
        for (let elt in refCountMap) {
          if (refCountMap[elt] !== 0) {
            return false}}
        return true}
      return refCountFn})()

    arrayB.map(eltB => refCount(eltB, 1));
    arrayA.map(eltA => refCount(eltA, -1));
    return refCount.isZero()}

這是小提琴

 var arr1 = [ {name: 'a', Val: 1}, {name: 'b', Val: 2}, {name: 'c', Val: 3} ]; var arr2 = [ {name: 'c', Val: 3}, {name: 'x', Val: 4}, {name: 'y', Val: 5}, {name: 'z', Val: 6} ]; var _isEqual = _.intersectionWith(arr1, arr2, _.isEqual);// common in both array var _difference1 = _.differenceWith(arr1, arr2, _.isEqual);//difference from array1 var _difference2 = _.differenceWith(arr2, arr1, _.isEqual);//difference from array2 console.log(_isEqual);// common in both array console.log(_difference1);//difference from array1 console.log(_difference2);//difference from array2 
 <script src="https://cdnjs.cloudflare.com/ajax/libs/lodash.js/4.17.5/lodash.js"></script> 

試試這個

function check(c,d){
  var a = c, b = d,flg = 0;
  if(a.length == b.length) 
  { 
     for(var i=0;i<a.length;i++) 
           a[i] != b[i] ? flg++ : 0; 
  } 
  else  
  { 
     flg = 1; 
  } 
  return flg = 0;
}

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM