जावास्क्रिप्ट वस्तुओं के दो सरणियों की तुलना करने के लिए jQuery का उपयोग करना


93

मेरे पास जावास्क्रिप्ट ऑब्जेक्ट्स के दो सरणियाँ हैं जो मैं यह देखने के लिए तुलना करना चाहूंगा कि क्या वे समान हैं। प्रत्येक सरणी में ऑब्जेक्ट समान क्रम में नहीं होंगे (और सबसे अधिक संभावना नहीं होगी)। प्रत्येक सरणी में 10 से अधिक ऑब्जेक्ट नहीं होने चाहिए। मुझे लगा कि jQuery के पास इस समस्या का एक सुंदर समाधान हो सकता है, लेकिन मैं बहुत अधिक ऑनलाइन खोजने में सक्षम नहीं था।

मुझे पता है कि एक ब्रूट नेस्टेड $.each(array, function(){})समाधान काम कर सकता है, लेकिन क्या कोई फ़ंक्शन में बनाया गया है जिसके बारे में मुझे जानकारी नहीं है?

धन्यवाद।

जवाबों:


277

एक आसान तरीका है ...

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

यदि उपरोक्त सही है, तो दोनों सरणियाँ समान हैं, भले ही तत्व अलग-अलग क्रम में हों।

नोट: यह JSON ऑब्जेक्ट्स का उपयोग करते समय केवल jquery संस्करणों के लिए काम करता है <3.0.0


12
+1, हालाँकि यह तब सही होता है जब आप किसी Array की तुलना उसी ऑब्जेक्ट से करते हैं जिसमें समान गुण होते हैं, f.ex[0,1] == {0:0,1:1,length=2}
David Hellsing

4
क्यों $(arr1).not(arr2).length == 0पर्याप्त नहीं है?
एलेक्सएक्सस

10
@Alexxus, आपको दोनों तुलनाओं की आवश्यकता है क्योंकि notफ़िल्टर फ़ंक्शन है, समानता फ़ंक्शन नहीं। इसके साथ प्रयास करें [1,2]और [1]। एक क्रम में, आपको मिलेगा [], और दूसरे में, आपको मिलेगा [2]
नोयियो

3
ध्यान दें कि यदि आपके पास एक सरणी में डुप्लिकेट हैं, तो यह सही वापस आ जाएगा। तो कुछ इस तरह है: `[1,1,2,2,3,3] == [1,2,3]` सत्य है।
Philll_t

3
jQuery notअब 3.0.0-rc1 के रूप में सामान्य वस्तुओं के साथ काम नहीं करता है। देखें github.com/jquery/jquery/issues/3147
मार्क-आंद्रे लाफ्यून

35

मैं आज भी इसकी तलाश में था और पाया: http://www.breakingpar.com/bkp/home.nsf/0/87256B280015193F87256BFB0077DFFD

पता नहीं है कि यह एक अच्छा समाधान है, हालांकि वे खाते में लिए गए कुछ प्रदर्शन विचारों का उल्लेख करते हैं।

मुझे jQuery सहायक विधि का विचार पसंद है। @ डेविड मैं आपके काम करने के तरीके की तुलना करना चाहूंगा:

jQuery.compare(a, b)

मैं करने के लिए मुझे समझ में नहीं आता:

$(a).compare(b)

जहाँ ए और बी सरणियाँ हैं। आम तौर पर जब आप $ (कुछ) आप DOM तत्वों के साथ काम करने के लिए एक चयनकर्ता स्ट्रिंग पास करेंगे।

सॉर्टिंग एरेज़ को सॉर्ट करने और 'कैशिंग' करने के बारे में:

  • मुझे नहीं लगता कि लूप के माध्यम से हर बार के बजाय विधि की शुरुआत में एक बार छांटना 'कैशिंग' है। आपके द्वारा तुलना (b) कॉल करने पर भी हर बार की तरह ही होगा। वह सिर्फ शब्दार्थ है, लेकिन ...
  • के लिए (var i = 0; t [i]; i ++) { ... यह लूप जल्दी खत्म हो जाता है अगर आपके t array में कहीं गलत मूल्य है, तो $ ([1, 2, 3, 4]) की तुलना करें। [1, झूठी, 2, 3]) रिटर्न सच !
  • अधिक महत्वपूर्ण बात यह है कि सरणी सॉर्ट () विधि जगह में सरणी को सॉर्ट करती है , इसलिए var b = t.sort () ... मूल सरणी की सॉर्ट की गई प्रतिलिपि नहीं बनाता है, यह मूल सरणी को सॉर्ट करता है और इसके लिए एक संदर्भ भी असाइन करता है यह बी में है । मुझे नहीं लगता कि तुलना विधि के साइड-इफेक्ट्स होने चाहिए।

ऐसा लगता है कि हमें उन पर काम करने से पहले सरणियों की नकल करना है। सबसे अच्छा जवाब मैं कैसे एक jQuery के तरीके से करने के लिए मिल सकता है कि कोई भी नहीं तो फिर से जॉन Resig एसओ पर यहाँ से था! जावास्क्रिप्ट में किसी ऑब्जेक्ट को गहरी क्लोन करने का सबसे कुशल तरीका क्या है? (वस्तु क्लोनिंग नुस्खा के सरणी संस्करण के लिए उनके उत्तर पर टिप्पणियाँ देखें)

जिस स्थिति में मुझे लगता है कि इसके लिए कोड होगा:

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]

2
वास्तव में मैं शायद 'तुलना' के बजाय इस विधि को 'arrayCompare' का नाम दूंगा क्योंकि यह एकमात्र ऐसी चीज है जिस पर काम करने के लिए इसे डिज़ाइन किया गया है ...
Anentropic

वास्तव में हाजिर। बहुत बहुत धन्यवाद।
dimitarvp

14

मेरा दृष्टिकोण काफी अलग था - मैंने 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');
}

NB: कृपया ध्यान दें कि उनकी विधि मानती है कि दोनों संग्रह एक समान फैशन में सॉर्ट किए गए हैं, यदि नहीं, तो यह आपको एक गलत परिणाम देगा!


1
मुझे अपनी इकाई परीक्षणों में सरणियों की तुलना करने के लिए एक सरल विधि की आवश्यकता थी, दो सरणियों के लिए एक ही क्रम का आश्वासन। यह बहुत अच्छा है, धन्यवाद।
aymericbeaumet

शुक्रिया आपने मेरा दिन बचा लिया
सौरभ कुमार शर्मा

12

दोनों सरणी को स्ट्रिंग में बदलें और तुलना करें

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

1
नेस्टेड सरणियों की तुलना करने के लिए अच्छा लगता है और जब आदेश महत्वपूर्ण होता है।
पियरे डे LESPINAY

3

मुझे यह चर्चा मिली क्योंकि मुझे सरणियों और वस्तुओं की तुलना करने के लिए एक गहरी आवश्यकता थी। यहां उदाहरणों का उपयोग करते हुए, मैं निम्नलिखित के साथ आया (स्पष्टता के लिए 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

3

मेरे मामले में तुलनात्मक सरणियों में केवल संख्याएँ और तार होते हैं । इस समाधान ने मेरे लिए काम किया:

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

1

मुझे नहीं लगता कि ऐसा करने के लिए एक अच्छा "jQuery" तरीका है, लेकिन अगर आपको दक्षता की आवश्यकता है, तो एक निश्चित कुंजी (एक अनोखी वस्तु क्षेत्रों में से एक) में से एक को मैप करें, और फिर अन्य सरणी के माध्यम से लूप करके तुलना करें और आपके द्वारा अभी बनाए गए नक्शे, या साहचर्य सरणी के खिलाफ तुलना करना।

यदि दक्षता कोई समस्या नहीं है, तो बस ए में प्रत्येक वस्तु की तुलना बी में हर वस्तु से करें। जब तक ए | और | बी | छोटे हैं, आपको ठीक होना चाहिए।


@Stefan, त्वरित प्रतिक्रिया के लिए धन्यवाद। क्या आप अपने मानचित्रण विचार के लिए उदाहरण कोड पोस्ट कर सकते हैं? धन्यवाद।
मेगामैट

1

यदि आप केवल सरणियों की सामग्री की तुलना करना चाहते हैं, तो एक उपयोगी 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

अच्छा समाधान, लेकिन मुझे यकीन नहीं है कि यह एक ही तत्व वाले सरणियों के लिए लेखांकन है, लेकिन एक अलग क्रम में।
मेगामाट

आप ले जा सकते हैं अगर (बराबर) झूठे लौटते हैं; $ .each के नीचे तक फिर से फंक्शन फायरिंग से बचने के लिए। और तुम बराबर लौट सकते हो; एक तुलना से बचने के लिए।
मैट

1

सरणी को स्ट्रिंग में बदलें और तुलना करें

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

1

सुधाकर आर से अच्छा एक लाइनर 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;
  }
});

0

जब jQuery के साथ कुछ सरणी तुलना करने के लिए देख मैं भी यह पाया। मेरे मामले में मेरे पास तार थे जो मैं जानता था कि सरणियाँ हैं:

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

लेकिन मुझे परवाह थी कि यह एक पूर्ण मैच था या केवल एक आंशिक मैच था, इसलिए मैंने सुधाकर आर के जवाब के आधार पर निम्नलिखित जैसे कुछ का उपयोग किया:

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

0

यदि डुप्लिकेट ऐसे मामले हैं जो [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()}

यहाँ खेलने के लिए बेला है


0

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>


-3

इसे इस्तेमाल करे

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

यह ए और बी दोनों को संशोधित करता है, और केवल पहले तत्व की तुलना करता है। WTF।
स्कॉटजे

1
@ScottJ Mr.AH प्रश्न दो सरणियों की तुलना करना है .. यदि दोनों सरणियों के बराबर होने के बाद छांटना एक [0] == b [0] हो। wtf आप bah
अपवाद

2
मुझे डर है कि मुझे नहीं पता कि एएच का मतलब क्या है, और Google कोई मदद नहीं करता था। लेकिन अगर मेरी टिप्पणी इतनी ऑफ-बेस थी, तो यह कोड 21 फरवरी को पूरी तरह से फिर से क्यों लिखा गया?
स्कॉट जे।

@ScottJ सबसे शायद AH === wtf
अपवाद
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.