आदेशों को समान अनदेखा करने की अपेक्षा करें


86

जैस्मीन के साथ परीक्षण करने का एक तरीका है यदि 2 सरणियों में समान तत्व होते हैं, लेकिन जरूरी नहीं कि एक ही क्रम में हों? अर्थात

array1 = [1,2,3];
array2 = [3,2,1];

expect(array1).toEqualIgnoreOrder(array2);//should be true

23
expect(array1.sort()).toEqual(array2.sort());?
बारिश।।

@ raina77ow मुझे लगता है कि यह भी काम करेगा।
डेविड का कहना है कि मोनिका

1
क्या मुझे इसका जवाब देना चाहिए?
बारिश।।

1
@ raina77ow वस्तुओं की एक सरणी होने पर यह थोड़ा अधिक जटिल हो जाता है। यह अच्छा होगा अगर जैस्मीन इसके लिए बॉक्स से बाहर कुछ है।
डेविड का कहना है कि मोनिका

2
मुझे चमेली में कुछ भी बहुत अच्छा नहीं लगा इसलिए वास्तव में लॉश को पेश किया (या आप इस तरह की चीजों के लिए अपने परीक्षण प्रोजेक्ट में अंडरस्कोर / अन्य जेएस कलेक्शन लाइब्रेरी का उपयोग कर सकते हैं)।
ktharsis

जवाबों:


61

यदि यह सिर्फ पूर्णांक या अन्य आदिम मूल्य हैं, तो आप sort()तुलना करने से पहले उन्हें देख सकते हैं।

expect(array1.sort()).toEqual(array2.sort());

यदि इसकी वस्तुएं, तो map()पहचानकर्ता को निकालने के लिए फ़ंक्शन के साथ संयोजन करें जो कि तुलना की जाएगी

array1 = [{id:1}, {id:2}, {id:3}];
array2 = [{id:3}, {id:2}, {id:1}];

expect(array1.map(a => a.id).sort()).toEqual(array2.map(a => a.id).sort());

डिफ़ॉल्ट सरणी सॉर्ट विधि संख्याओं के लिए स्ट्रिंग तुलना का उपयोग करती है। "10" < "2" === true
श्मिट

[10, 2, 1].sort() ---> [1, 10, 2]
श्मिट्टी

7
@Shiddty मैं नहीं देखता कि यह इस मामले में कैसे मायने रखता है। जब तक आदेश दोनों सरणियों के लिए समान है, तब तक यह ठीक होना चाहिए।
रंगीन पांडा

1
निष्पक्ष बिंदु। यह ध्यान देने योग्य है कि sortजगह में होता है, हालांकि। (यह उस उदाहरण को उत्परिवर्तित करता है जिस पर इसे कहा जाता है)
श्मिट्टी

1
इस उत्तर का ऑब्जेक्ट भाग वास्तव में सत्यापित नहीं करेगा कि ऑब्जेक्ट मेल खाते हैं, क्योंकि यह केवल मैप किए गए सरणियों की तुलना कर रहा है। आपको मानचित्र की आवश्यकता नहीं है, sortएक वैकल्पिक फ़ंक्शन लेता है जिसका उपयोग वह तुलना करने के लिए कर सकता है।
slifty

19

चमेली संस्करण 2.8 और बाद में है

jasmine.arrayWithExactContents()

जो यह उम्मीद करता है कि किसी सरणी में किसी भी क्रम में सूचीबद्ध तत्व ठीक हैं।

array1 = [1,2,3];
array2 = [3,2,1];
expect(array1).toEqual(jasmine.arrayWithExactContents(array2))

Https://jasmine.github.io/api/3.4/jasmine.html देखें


13

सरल...

array1 = [1,2,3];
array2 = [3,2,1];

expect(array1).toEqual(jasmine.arrayContaining(array2));

7
अच्छा जवाब! आपको यह भी जांचने की आवश्यकता है कि लंबाई समान है, अन्यथा आपको [1,2,3,4] और [3,2,1] पर एक झूठी सकारात्मक जानकारी मिलेगी।
क्रिस्टियन हैनकैंप

10
// check if every element of array2 is element of array1
// to ensure [1, 1] !== [1, 2]
array2.forEach(x => expect(array1).toContain(x))

// check if every element of array1 is element of array2
// to ensure [1, 2] !== [1, 1]
array1.forEach(x => expect(array2).toContain(x))

// check if they have equal length to ensure [1] !== [1, 1]
expect(array1.length).toBe(array2.length)

2
कुछ समय और स्मृति का एक गुच्छा बचाने .forEachके .mapलिए उपयोग करें ।
डार्कहॉग

1
: दुर्भाग्य से यह निम्नलिखित सरणियों के साथ पारित करेंगे, भले ही वे अलग हैं array1 = [1, 2],array2 = [1, 1]
redbmk

2
अच्छा पकड़ @redbmk मैंने इसके लिए एक चेक जोड़ा, धन्यवाद!
जनक बेक

मुझे लगता है कि अभी भी एक मुद्दा है - क्या होगा यदि सरणियां हैं [1,1,2]और [1,2,2]? शायद हर एक या कुछ के लिए एक मानचित्र का उपयोग? उदाहरण के array1.reduce((map, item) => { map.set(item, (map.get(item) || 0) + 1)), new Map())लिए दोनों सरणियों के माध्यम से, फिर उनके माध्यम से लूप करें और जांचें कि मात्रा समान हैं? बहुत पुनरावृत्तियों की तरह लगता है, लेकिन अधिक पूरी तरह से होगा।
19 पर redbmk

नियंत्रण सरणी से बहिष्करण का उपयोग किया जा सकता है (जब पाया गया तत्व को हटा दें, तो जांच की लंबाई अंत में 0 है), लेकिन यह नियमित मामलों में प्रयास के लायक नहीं है।
जीवनरक्षक

4

आप मानक jest से अपेक्षानुरूपता (सरणी) का उपयोग कर सकते हैं:

  const expected = ['Alice', 'Bob'];
  it('matches even if received contains additional elements', () => {
    expect(['Alice', 'Bob', 'Eve']).toEqual(expect.arrayContaining(expected));
  });

2

हंसी-विस्तारित पैकेज हमें कुछ कथनों हमारे परीक्षणों सरल करने के लिए प्रदान करता है, यह कम वर्बोज़ है और परीक्षण में नाकाम रहने के लिए त्रुटि अधिक स्पष्ट है।

इस मामले के लिए हम IncludeSameMembers का उपयोग कर सकते हैं

expect([{foo: "bar"}, {baz: "qux"}]).toIncludeSameMembers([{baz: "qux"}, {foo: "bar"}]);

1
//Compare arrays without order
//Example
//a1 = [1, 2, 3, 4, 5]
//a2 = [3, 2, 1, 5, 4]
//isEqual(a1, a2) -> true
//a1 = [1, 2, 3, 4, 5];
//a2 = [3, 2, 1, 5, 4, 6];
//isEqual(a1, a2) -> false


function isInArray(a, e) {
  for ( var i = a.length; i--; ) {
    if ( a[i] === e ) return true;
  }
  return false;
}

function isEqArrays(a1, a2) {
  if ( a1.length !== a2.length ) {
    return false;
  }
  for ( var i = a1.length; i--; ) {
    if ( !isInArray( a2, a1[i] ) ) {
      return false;
    }
  }
  return true;
}

0
function equal(arr1, arr2){
    return arr1.length === arr2.length
    &&
    arr1.every((item)=>{
        return arr2.indexOf(item) >-1
    }) 
    &&
    arr2.every((item)=>{
        return arr1.indexOf(item) >-1
    })
}

यहाँ विचार पहले यह निर्धारित करना है कि दो सरणियों की लंबाई समान है, तो जांचें कि क्या सभी तत्व दूसरे के सरणी में हैं।


यह मदों की आवृत्ति को ध्यान में नहीं रखता है: equal([1, 1, 2], [1, 2, 2])रिटर्न true
MarkMYoung

0

यहां एक समाधान है जो किसी भी संख्या या सरणियों के लिए काम करेगा

https://gist.github.com/tvler/cc5b2a3f01543e1658b25ca567c078e4

const areUnsortedArraysEqual = (...arrs) =>
  arrs.every((arr, i, [first]) => !i || arr.length === first.length) &&
  arrs
    .map(arr =>
      arr.reduce(
        (map, item) => map.set(item, (map.get(item) || 0) + 1),
        new Map(),
      ),
    )
    .every(
      (map, i, [first]) =>
        !i ||
        [...first, ...map].every(([item]) => first.get(item) === map.get(item)),
    );

कुछ परीक्षण (इस प्रश्न के कुछ उत्तर एक ही मूल्य के कई मदों के साथ सरणियों का हिसाब नहीं देते हैं, इसलिए [1, 2, 2] और [1, 2] गलत तरीके से सही वापस आएंगे)

[1, 2] true
[1, 2], [1, 2] true
[1, 2], [1, 2], [1, 2] true
[1, 2], [2, 1] true
[1, 1, 2], [1, 2, 1] true
[1, 2], [1, 2, 3] false
[1, 2, 3, 4], [1, 2, 3], [1, 2] false
[1, 2, 2], [1, 2] false
[1, 1, 2], [1, 2, 2] false
[1, 2, 3], [1, 2], [1, 2, 3] false

0

यह एल्गोरिथ्म सरणियों के लिए महान है जहां प्रत्येक आइटम अद्वितीय है। यदि नहीं, तो आप डुप्लिकेट की जांच के लिए कुछ में जोड़ सकते हैं ...

tests = [
  [ [1,0,1] , [0,1,1] ],
  [ [1,0,1] , [0,0,1] ], //breaks on this one...
  [ [2,3,3] , [2,2,3] ], //breaks on this one also...
  [ [1,2,3] , [2,1,3] ],
  [ [2,3,1] , [1,2,2] ],
  [ [2,2,1] , [1,3,2] ]
]

tests.forEach(function(test) {
  console.log('eqArraySets( '+test[0]+' , '+test[1]+' ) = '+eqArraySets( test[0] , test[1] ));
});


function eqArraySets(a, b) {
	if ( a.length !== b.length ) { return false; }
	for ( var i = a.length; i--; ) {
		if ( !(b.indexOf(a[i])>-1) ) { return false; }
		if ( !(a.indexOf(b[i])>-1) ) { return false; }
	}
	return true;
}


0

इस दृष्टिकोण ने सैद्धांतिक रूप से सबसे खराब स्थिति वाले रन-टाइम प्रदर्शन को खराब कर दिया है, लेकिन, क्योंकि यह सरणी पर कोई लेखन नहीं करता है, यह कई परिस्थितियों में तेज़ हो सकता है (अभी तक प्रदर्शन का परीक्षण नहीं किया गया है):

चेतावनी: जैसा कि तोरबेन ने टिप्पणियों में बताया है, यह दृष्टिकोण केवल तभी काम करता है जब दोनों सरणियों में अद्वितीय (गैर-दोहराए जाने वाले) तत्व होते हैं (यहां अन्य उत्तरों में से कई की तरह)।

/**
 * Determine whether two arrays contain exactly the same elements, independent of order.
 * @see /programming/32103252/expect-arrays-to-be-equal-ignoring-order/48973444#48973444
 */
function cmpIgnoreOrder(a, b) {
  const { every, includes } = _;
  return a.length === b.length && every(a, v => includes(b, v));
}

// the following should be all true!
const results = [
  !!cmpIgnoreOrder([1,2,3], [3,1,2]),
  !!cmpIgnoreOrder([4,1,2,3], [3,4,1,2]),
  !!cmpIgnoreOrder([], []),
  !cmpIgnoreOrder([1,2,3], [3,4,1,2]),
  !cmpIgnoreOrder([1], []),
  !cmpIgnoreOrder([1, 3, 4], [3,4,5])
];

console.log('Results: ', results)
console.assert(_.reduce(results, (a, b) => a && b, true), 'Test did not pass!');
<script src="https://cdnjs.cloudflare.com/ajax/libs/lodash.js/4.17.5/lodash.js"></script>


1
आपके कहने का क्या मतलब है जब यह बहुत सारी प्रतियां बनाता है? Array#sortतरह जगह में arrays।
देलराज

1
इन सरणियों के लिए विफल: [1,1,2,3], [3,3,1,2]।
तोर्बेन कोहलमीयर

1
@TorbenKohlmeier धन्यवाद, मैंने अपना उत्तर अपडेट किया (गैर-अद्वितीय सरणियों के संबंध में हार को स्वीकार करते हुए)
डॉमी


-1

आप कुछ इस तरह का उपयोग कर सकते हैं:

expect(array1).toEqual(jasmine.arrayContaining(array2));

आयात याद है jasmine। या इसे अपने में जोड़ें.eslintrc


-3

जेस्ट में एक फ़ंक्शन होता है जिसे expect.arrayContainingआप चाहते हैं कि वास्तव में क्या करेंगे:

expect(array1).toEqual(expect.arrayContaining(array2))

आप जाँच कर सकते हैं कि क्या वे समान लंबाई के साथ हैं, क्योंकि परीक्षण पास हो जाएगा

अपेक्षित सरणी प्राप्त सरणी का एक सबसेट है

डॉक्टर के अनुसार।

संपादित करें: क्षमा करें कि मैंने चमेली टैग को नोटिस नहीं किया, यह एक तरीका है जो जेस्ट के साथ काम करता है

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