2012-02-17 15 views
8

this answer में एक साधारण कार्य है जो सरणी मूल्यों वाले सरणी के लिए सरणी समानता को वापस कर देगा।यह जावास्क्रिप्ट सरणी समानता क्यों साबित करता है या कैसे?

हालांकि, मुझे यकीन नहीं है कि यह क्यों काम करता है। यहां फ़ंक्शन है:

function arrays_equal(a,b) { return !!a && !!b && !(a<b || b<a); } 

मुझे अधिकतर दूसरी छमाही में दिलचस्पी है; इस बिट:

!(a<b || b<a) 

क्यों < और > काम जब सरणियों की तुलना करता है लेकिन == नहीं करता है?

जावास्क्रिप्ट के भीतर विधियों से कम और उससे अधिक कैसे काम करते हैं?

उत्तर

10

</> के साथ, सरणी पहले स्ट्रिंग में परिवर्तित हो जाती हैं, और इस तरह समानता की जांच करने का एक विश्वसनीय तरीका प्रदान नहीं करते हैं।

क्योंकि वस्तुओं संदर्भ द्वारा जाँच की जाती == काम नहीं करता:

[] == []; // false, two separate objects 

var a = []; 
a == a; // true, refer to the same object 

</> चाल से दोषपूर्ण है:

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

!(a<b || b<a); // true 

यह true का आकलन करती है क्योंकि वे दोनों स्ट्रिंग में बदला "1,2,3" चेक किए जाने से पहले (</> ऑब्जेक्ट्स के लिए "सीधे" काम न करें)।

तो मूल रूप से, आप स्ट्रिंग की समानता की तुलना कर रहे हैं। स्ट्रिंग्स के लिए, a == b वास्तव में !(a<b || b<a) - </> स्ट्रिंग्स चेक कैरेक्टर कोड के लिए समान है, इसलिए दो बराबर स्ट्रिंग न तो "छोटे" और न ही "अधिक" हैं क्योंकि स्ट्रिंग में किसी भी वर्ण कोड के मामले में यह मामला नहीं है।

+0

+1 कुछ नया जे एस में प्रत्येक दिन हो रही है: जब आप गैर देशी JSON.stringify उपयोग कर रहे हैं, यह विचित्र बातें चक्रीय आदानों के लिए की तरह कर सकते हैं। लवली भाषा – Sarfraz

+0

@ सर्फ्राज़: हाँ, जब तक कि आप कुछ बुरा डिबगिंग के बाद इस तरह की चीज़ों को नहीं खोज लेते ... – pimvdb

+0

हाल ही में इसे सीखना शुरू कर दिया है ** गंभीरता से ** आगे बढ़ना :)। आपके पास एक ब्लॉग होना चाहिए :) – Sarfraz

4

आप == का उपयोग कर किसी भी दो ऑब्जेक्ट की तुलना कर सकते हैं। लेकिन चूंकि> और < वस्तुओं के लिए परिभाषित नहीं हैं, वे तारों में परिवर्तित हो जाते हैं। इसलिए, [1,2,3]>[2,1,3] वास्तव में "1,2,3">"2,1,3"

+1

यह सही नहीं है। रूपांतरण हमेशा स्ट्रिंग नहीं है। [11.8.5] (http://es5.github.com/#x11.8.5) निर्दिष्ट करता है कि ऑब्जेक्ट रूपांतरण प्रकार संकेत '' संख्या 'के साथ होता है, इसलिए 'arrays_equal (नई तिथि (1), 1)' सत्य है '। –

+0

धन्यवाद; और माइक को उनकी टिप्पणी में स्पष्टीकरण के लिए! –

5

हालांकि, मुझे यकीन नहीं है कि यह क्यों काम करता है।

यह काम नहीं करता है। पर विचार करें

arrays_equal(["1,2"], [1,2]) 

सच का उत्पादन भले ही तत्व के लिहाज से तुलना के आधार पर सरणी समानता के किसी भी परिभाषा से, वे अलग हैं।

arrays_equal([[]], []) 

और

arrays_equal([""], []) 

भी नकली सकारात्मक रहे हैं।

, बस के रूप में जोड़ने से

arrays_equal(["1,2",3], [1,"2,3"]) 

arrays_equal(
    ["",","], 
    [",",""]) 

संपादित प्रदर्शन किया length जाँच में मदद नहीं करेगा:

आप संरचनात्मक समानता परीक्षण करने के लिए एक संक्षिप्त रास्ता चाहते हैं, मेरा सुझाव है:

function structurallyEquivalent(a, b) { 
    return JSON.stringify(a) === JSON.stringify(b); 
} 

यह इनपुट पर शुरुआती रूप से अलग नहीं होता है जो स्पष्ट रूप से भिन्न होते हैं - यह ऑब्जेक्ट ग्राफ दोनों को चलता है चाहे वे कितने असमान हैं, लेकिन इसमें कार्य भी करता है ओपी।

एक चेतावनी:

var input = []; 
input[0] = input; 
+1

प्राइमेटिव के लिए भी, 'JSON.stringify' पूरी तरह भरोसेमंद नहीं हो सकता है। '[,]' और '[null]' पर विचार करें। – pimvdb

+0

@pimvdb, ज़रूर। यह 'शून्य 'और' अपरिभाषित '/ elipsis conflates लेकिन जावास्क्रिप्ट' == 'करता है। ओपी में कुछ भी '===' ''=' के लिए प्राथमिकता व्यक्त करता है। –

+0

धन्यवाद, आपके उत्तर ने @ pimvdb के साथ मेरी समझ में आगे सहायता की। –

संबंधित मुद्दे