सरणियों की तुलना करने के लिए लॉश का उपयोग करना (ऑर्डर के बिना आइटम अस्तित्व)


125

मुझे पता है कि मैं इसे लूप का उपयोग करके कर सकता हूं, लेकिन मैं इसे करने का एक सुंदर तरीका खोजने की कोशिश कर रहा हूं:

मेरे पास दो सरणियाँ हैं:

var array1 = [['a', 'b'], ['b', 'c']];
var array2 = [['b', 'c'], ['a', 'b']];

मैं lodashयह पुष्टि करने के लिए उपयोग करना चाहता हूं कि उपरोक्त दो सरणियां समान हैं। 'समान' से मेरा मतलब है कि इसमें कोई वस्तु नहीं है, array1जो इसमें निहित नहीं है array2

इन वस्तुओं के बीच समानता की जाँच के संदर्भ में:

['a', 'b'] == ['b', 'a'] 

या

['a', 'b'] == ['a', 'b'] 

दोनों काम करते हैं क्योंकि पत्र हमेशा क्रम में होंगे।

जवाबों:


224

यदि आप बाहरी सरणी को सॉर्ट करते हैं, तो आप उपयोग कर सकते हैं _.isEqual()क्योंकि आंतरिक सरणी पहले से ही सॉर्ट की गई है।

var array1 = [['a', 'b'], ['b', 'c']];
var array2 = [['b', 'c'], ['a', 'b']];
_.isEqual(array1.sort(), array2.sort()); //true

ध्यान दें कि .sort()सरणियों को बदल देगा। यदि आपके लिए यह समस्या है, तो पहले (उदाहरण के लिए) .slice()या प्रसार ऑपरेटर ( ...) का उपयोग करके एक प्रतिलिपि बनाएं ।

या, जैसा कि डैनियल ब्यूक नीचे टिप्पणी में सुझाता है:

_.isEqual(_.sortBy(array1), _.sortBy(array2))

Lodash की sortBy()सरणी को म्यूट नहीं किया जाएगा।


6
ध्यान रखें कि array.sort () मूल सरणी को बदल रहा है। हो सकता है कि यह बेहतर हो: var array1 = [['a', 'b'], ['b', 'c']]; var array2 = [['b', 'c'], ['a', 'b']]; _.isEqual ([... array1] .sort (), [... array2] .sort ()); // सच
यानिव एफ़्रैम

3
दो वाक्यों को जोड़ा गया है जो .sort()उत्परिवर्तित करता है और उपयोगकर्ता के लिए समस्या होने पर सबसे पहले कॉपी करने के विकल्प सुझाता है।
ट्रॉट

6
यदि आप पहले से ही लॉश का उपयोग कर रहे हैं, तो आप _.isEqual(_.sortBy(array1), _sortBy(array2))उत्परिवर्तन को रोकने के लिए कर सकते हैं ।
डैनियल ब्यूक

1
@DanielBudick धन्यवाद! मैंने उसे उत्तर में जोड़ दिया है। शानदार सुझाव।
ट्रॉट

33

आप lodashs उपयोग कर सकते हैं xorइस के लिए

doArraysContainSameElements = _.xor(arr1, arr2).length === 0

यदि आप सरणी [1, 1] को सरणी [1] से अलग मानते हैं तो आप प्रदर्शन में थोड़ा सुधार कर सकते हैं:

doArraysContainSameElements = arr1.length === arr2.length === 0 && _.xor(arr1, arr2).length === 0

1
Arrays को वैसे भी हल करने की आवश्यकता है।
सोवात्थ सोक

1
नए संस्करण के लिए यह बेहतर तरीका होना चाहिए
लियोनार्डो

@Sovattha सोक सरणियों को हल करने की आवश्यकता नहीं है। करना _.xor([3,4], [4,3]).length == 0आपको सच्चा लगेगा।
निकोले

1
सावधानी का एक शब्द: यह तकनीक "छोटे" सरणियों के लिए अच्छी तरह से काम करती है, लेकिन यह एक दर्द प्रदर्शन और स्मृति-वार हो सकता है यदि आपके सरणियाँ विशाल हैं और ज्यादातर अलग-अलग हैं क्योंकि _.xor () वायाए को पहले अंतर से अलग रखेगा। दूसरे शब्दों में यह पता चला पहले अंतर पर तेजी से वापस नहीं आता है।
XDS

6

'वही' से मेरा मतलब है कि array1 में कोई आइटम नहीं है जो array2 में समाहित नहीं है।

आप () और अंतर () इस बात के लिए है, जो अच्छी तरह से काम करता है समतल उपयोग करें यदि आप अगर वहाँ में आइटम हैं परवाह नहीं है हो सकता है array2कि नहीं कर रहे हैं में array1। ऐसा लगता है कि आप पूछ रहे हैं array1 array2 का सबसेट है ?

var array1 = [['a', 'b'], ['b', 'c']];
var array2 = [['b', 'c'], ['a', 'b']];

function isSubset(source, target) {
    return !_.difference(_.flatten(source), _.flatten(target)).length;
}

isSubset(array1, array2); // → true
array1.push('d');
isSubset(array1, array2); // → false
isSubset(array2, array1); // → true

4

यहां पहले से ही उत्तर हैं, लेकिन यहां मेरा शुद्ध जेएस कार्यान्वयन है। मुझे यकीन नहीं है कि यह इष्टतम है, लेकिन यह सुनिश्चित है कि यह पारदर्शी, पठनीय और सरल है।

// Does array a contain elements of array b?
const contains = (a, b) => new Set([...a, ...b]).size === a.length
const isEqualSet = (a, b) => contains(a, b) && contains(b, a)

में तर्क contains()यह है कि यदि aसभी तत्व शामिल हैं b, तो उन्हें एक ही सेट में रखने से आकार नहीं बदलेगा।

उदाहरण के लिए, यदि const a = [1,2,3,4]और const b = [1,2]फिर new Set([...a, ...b]) === {1,2,3,4}। जैसा कि आप देख सकते हैं, परिणामी सेट के समान तत्व हैं a

वहाँ से, इसे और अधिक संक्षिप्त बनाने के लिए, हम इसे नीचे तक उबाल सकते हैं:

const isEqualSet = (a, b) => {
  const unionSize = new Set([...a, ...b])
  return unionSize === a.length && unionSize === b.length
}

1

PURE JS (कार्य भी करता है जब सरणियाँ और उपवाक्य में 2 से अधिक तत्व होते हैं जो मनमाने आदेश के साथ होते हैं)। यदि स्ट्रिंग्स में पैराट्रल कैरेक्टर (यूटीएफ हो सकता है) के ,रूप में उपयोग होता है जो स्ट्रिंग्स में उपयोग join('-')नहीं किया जाता है

array1.map(x=>x.sort()).sort().join() === array2.map(x=>x.sort()).sort().join()


0

हम _.differenceफ़ंक्शन का उपयोग यह देखने के लिए कर सकते हैं कि कोई अंतर है या नहीं।

function isSame(arrayOne, arrayTwo) {
   var a = _.unique(arrayOne),
       b = _.unique(arrayTwo);

   if (a.length <= b.length) {
      a = arrayTwo;
      b = arrayOne;
      return _.isEmpty(_.difference(a.sort(), b.sort()));
   } else {
      return false;
   }

}

// examples
console.log(isSame([1, 2, 3], [1, 2, 3])); // true
console.log(isSame([1, 2, 4], [1, 2, 3])); // false
console.log(isSame([1, 2], [2, 3, 1])); // false
console.log(isSame([2, 3, 1], [1, 2])); // false

// Test cases pointed by Mariano Desanze, Thanks.
console.log(isSame([1, 2, 3], [1, 2, 2])); // false
console.log(isSame([1, 2, 2], [1, 2, 2])); // true
console.log(isSame([1, 2, 2], [1, 2, 3])); // false

उम्मीद है इससे आपको मदद मिलेगी।


5
गलत, आपके फ़ंक्शन के trueलिएconsole.log(isSame([1,2], [2,3,1]));
डेविड लिन

3
इसे इंगित करने के लिए @DavidLin धन्यवाद। मैंने उस मामले पर विचार करने के लिए बदलाव किए हैं। धन्यवाद और असुविधा के लिए खेद है।
अमितेश

2
यदि लंबाई समान नहीं है, तो आपको a & b के लिए स्थान बदलने की आवश्यकता नहीं है। यदि लंबाई भिन्न होती है, तो वे पहले से ही समान नहीं हो सकती हैं, इसलिए यदि (arrayOne.lenght! == arrayTwo.lenght) गलत है;
एलेक्स

1
-1 उन aऔर bचर होने में कोई मतलब नहीं है । आप केवलif-then भाग के अंदर उन चरों का उपयोग करते हैं , और पहली बात यह है कि आप उन मूल्यों को पंक्ति 2 में लोड करते हैं। मुझे लगता है कि निम्नलिखित एकल पंक्ति बिल्कुल उसी तरह काम करेगी return arrayOne.length <= arrayTwo.length && _.isEmpty(_.difference(arrayTwo.sort(), arrayTwo.sort());:। और में <=भी सुधार किया जा सकता है ===
मैरियानो देसनज़े

1
और _.difference1 तर्क के लापता आइटम को वापस करेगा, लेकिन 2 में से गायब आइटम नहीं। तो trueजब आप 2 में 1 पर आइटम दोहराते हैं तो यह गलत तरीके से वापस आ जाएगा isSame([1, 2, 3], [1, 2, 2]):।
मैरियन डेसांज़

0

संपादित करें: मैंने इस प्रश्न के बहुआयामी पहलू को याद किया, इसलिए मैं इसे यहाँ छोड़ रहा हूँ अगर यह लोगों को एक आयामी सरणियों की तुलना करने में मदद करता है

यह एक पुराना प्रश्न है, लेकिन मुझे उपयोग करने की गति के साथ समस्याएँ आ रही थीं .sort()या sortBy(), इसलिए मैंने इसके बजाय इसका उपयोग किया:

function arraysContainSameStrings(array1: string[], array2: string[]): boolean {
  return (
    array1.length === array2.length &&
    array1.every((str) => array2.includes(str)) &&
    array2.every((str) => array1.includes(str))
  )
}

यह तेजी से विफल होने का इरादा था, और मेरे उद्देश्यों के लिए ठीक काम करता है।


क्या अंतिम जांच वास्तव में आवश्यक है? array1.every((str) => array2.includes(str))पर्याप्त होगा। इसके अलावा, ओपी लाकेश का उपयोग करना चाहता था, आपको कम से कम यह कहना चाहिए कि आप एक वेनिलाजेएस समाधान का प्रस्ताव क्यों देते हैं (... अब जो हमारे पास है और इसमें सभी शामिल हैं ...)। कृपया एक उदाहरण भी प्रदान करें कि प्रदान की गई समस्या (2-आयामी सरणियों) में अपने फ़ंक्शन को कैसे लागू करें।
लाइन-ओ

यह एक अच्छा बिंदु है - मैंने इसके बहुआयामी पहलू को संबोधित नहीं किया है, न कि इसे दर्ज करने की आवश्यकता है। मुझे लगा कि lodash methods to compare arrays without considering orderआधुनिक जावास्क्रिप्ट में एक विकल्प देखने के लिए यह उपयोगी होगा कि कोई भी खोज (जैसा मैंने किया) । दूसरी जाँच आवश्यक है क्योंकि arraysContainSameStrings(['1', '2', '2'], ['1', '2', '3'])यह सच है अन्यथा। मैं इसे यहाँ छोड़ दूँगा, क्योंकि यह मदद कर सकता है, लेकिन मैं सराहना करता हूँ कि मैंने इस प्रश्न का उत्तर नहीं दिया है
charliematters
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.