जावास्क्रिप्ट में कोई तार्किक Xor क्यों नहीं है?
जावास्क्रिप्ट में कोई तार्किक Xor क्यों नहीं है?
जवाबों:
जावास्क्रिप्ट अपने पूर्वजों को C पर वापस लाती है, और C के पास तार्किक XOR ऑपरेटर नहीं है। मुख्यतः क्योंकि यह उपयोगी नहीं है। बिटवाइज़ एक्सओआर बेहद उपयोगी है, लेकिन मेरे सभी वर्षों के प्रोग्रामिंग में मुझे कभी भी तार्किक एक्सओआर की आवश्यकता नहीं थी।
यदि आपके पास दो बूलियन चर हैं, तो आप XOR की नकल कर सकते हैं:
if (a != b)
दो मनमाने ढंग से चर के साथ आप !
उन्हें बूलियन मान के लिए इस्तेमाल कर सकते हैं और फिर उसी चाल का उपयोग कर सकते हैं:
if (!a != !b)
हालांकि यह बहुत अस्पष्ट है और निश्चित रूप से एक टिप्पणी के लायक होगा। वास्तव में, आप इस बिंदु पर बिटवॉयर XOR ऑपरेटर का भी उपयोग कर सकते हैं, हालांकि यह मेरे स्वाद के लिए बहुत अधिक चतुर होगा:
if (!a ^ !b)
जावास्क्रिप्ट में एक बिटवाइज़र XOR ऑपरेटर है: ^
var nb = 5^9 // = 12
आप इसे बूलियन के साथ उपयोग कर सकते हैं और यह 0 या 1 के रूप में परिणाम देगा (जिसे आप वापस बूलियन में बदल सकते हैं, जैसे result = !!(op1 ^ op2)
)। लेकिन जैसा कि जॉन ने कहा, यह इसके बराबर है result = (op1 != op2)
, जो स्पष्ट है।
true^true
है 0, और false^true
है 1.
||
और &&
गैर- बूलियंस पर तार्किक ऑपरेटरों के रूप में इस्तेमाल किया जा सकता है (उदाहरण के लिए एक सत्य मान देता है 5 || 7
, "bob" && null
एक गलत मूल्य देता है) लेकिन ^
नहीं कर सकता। उदाहरण के लिए, 5 ^ 7
2 के बराबर है, जो सत्य है।
(true ^ false) !== true
जो इसे उन पुस्तकालयों से परेशान कर रहा है जिनके लिए वास्तविक
a ^= true
बूलियन्स को टॉगल करने के लिए किसी तरह का उपयोग कर रहा था और यह कुछ मशीनों जैसे फोन पर विफल रहता है।
जावास्क्रिप्ट में कोई वास्तविक तार्किक बूलियन ऑपरेटर नहीं हैं (हालांकि !
काफी करीब आता है)। एक तार्किक ऑपरेटर केवल true
या false
ऑपरेंड के रूप में ले जाएगा और केवल true
या वापस आ जाएगा false
।
जावास्क्रिप्ट में &&
और ||
सभी प्रकार के ऑपरेंड लें और सभी प्रकार के मज़ेदार परिणाम (जो भी आप उन्हें खिलाते हैं) वापस करें।
साथ ही एक तार्किक ऑपरेटर को हमेशा दोनों ऑपरेंड के मूल्यों को ध्यान में रखना चाहिए।
जावास्क्रिप्ट में &&
और ||
एक आलसी शॉर्टकट ले लो और कुछ मामलों में दूसरे ऑपरेंड का मूल्यांकन न करें और इस तरह इसके दुष्प्रभावों की उपेक्षा करें। यह व्यवहार एक तार्किक एक्सोर के साथ फिर से बनाना असंभव है।
a() && b()
a()
यदि यह गलत है तो परिणाम का मूल्यांकन करता है और लौटाता है। अन्यथा यह मूल्यांकन करता है b()
और परिणाम देता है। इसलिए लौटा परिणाम सत्य है यदि दोनों परिणाम सत्य हैं, और मिथ्या है।
a() || b()
a()
सत्य होने पर परिणाम का मूल्यांकन करता है और वापस करता है। अन्यथा यह मूल्यांकन करता है b()
और परिणाम देता है। इसलिए लौटा हुआ परिणाम मिथ्या है अगर दोनों परिणाम गलत हैं, और सत्य अन्यथा।
इसलिए सामान्य विचार यह है कि पहले बाएं ऑपरेंड का मूल्यांकन किया जाए। आवश्यक होने पर ही सही संचालन का मूल्यांकन किया जाता है। और अंतिम मूल्य परिणाम है। यह परिणाम कुछ भी हो सकता है। ऑब्जेक्ट्स, नंबर, स्ट्रिंग्स .. जो भी हो!
इससे चीजों को लिखना संभव हो जाता है
image = image || new Image(); // default to a new Image
या
src = image && image.src; // only read out src if we have an image
लेकिन इस परिणाम के सत्य मूल्य का उपयोग यह तय करने के लिए भी किया जा सकता है कि क्या "वास्तविक" तार्किक ऑपरेटर सही या गलत लौटा होगा।
इससे चीजों को लिखना संभव हो जाता है
if (typeof image.hasAttribute === 'function' && image.hasAttribute('src')) {
या
if (image.hasAttribute('alt') || image.hasAttribute('title')) {
लेकिन एक "तार्किक" xor ऑपरेटर ( ^^
) को हमेशा दोनों ऑपरेंड का मूल्यांकन करना होगा। यह इसे अन्य "तार्किक" ऑपरेटरों के लिए अलग बनाता है जो आवश्यक होने पर ही दूसरे ऑपरेंड का मूल्यांकन करते हैं। मुझे लगता है यही कारण है कि भ्रम से बचने के लिए, जावास्क्रिप्ट में कोई "तार्किक" xor नहीं है।
तो क्या होगा यदि दोनों ऑपरेंड गलत हैं? दोनों को लौटाया जा सकता था। लेकिन केवल एक ही लौटाया जा सकता है। कौनसा? पहले वाला? या दूसरा वाला? मेरा अंतर्ज्ञान मुझे पहले वापस करने के लिए कहता है लेकिन आमतौर पर "तार्किक" ऑपरेटर बाएं से दाएं का मूल्यांकन करते हैं और अंतिम मूल्यांकन किए गए मूल्य को वापस करते हैं। या हो सकता है कि एक सरणी जिसमें दोनों मान हों?
और यदि एक ऑपरेंड सत्य है और दूसरा ऑपरेंड झूठा है, तो एक एक्सोर को सच्चाई को वापस करना चाहिए। या हो सकता है कि एक सरणी जिसमें सत्य एक है, उसे पिछले मामले के साथ संगत करने के लिए?
और अंत में, यदि दोनों ऑपरेंड सत्य हैं तो क्या होना चाहिए? आप कुछ झूठा उम्मीद करेंगे। लेकिन कोई मिथ्या परिणाम नहीं हैं। इसलिए ऑपरेशन को कुछ भी वापस नहीं करना चाहिए। तो शायद undefined
या .. एक खाली सरणी? लेकिन एक खाली सरणी अभी भी सत्य है।
ऐरे एप्रोच लेते हुए आप जैसे हालात खत्म हो जाएंगे if ((a ^^ b).length !== 1) {
। बहुत ज्यादा उलझन।
वहाँ है ... की तरह:
if( foo ? !bar : bar ) {
...
}
या पढ़ने में आसान:
if( ( foo && !bar ) || ( !foo && bar ) ) {
...
}
क्यों? पता नहीं।
क्योंकि जावास्क्रिप्ट डेवलपर्स ने सोचा कि यह अनावश्यक होगा क्योंकि इसे अन्य, पहले से लागू, तार्किक ऑपरेटरों द्वारा व्यक्त किया जा सकता है।
आप अच्छी तरह से सिर्फ नंद के साथ गन कर सकते हैं और इसे thats, आप उस से हर दूसरे संभव तार्किक संचालन को प्रभावित कर सकते हैं।
मुझे व्यक्तिगत रूप से लगता है कि इसके ऐतिहासिक कारण हैं जो c- आधारित वाक्यविन्यास भाषाओं से चलते हैं, जहाँ मेरा ज्ञान xor मौजूद नहीं है या कम से कम बेहद असामान्य है।
हां, बस निम्नलिखित करें। यह मानते हुए कि आप बूलियन्स ए और बी के साथ काम कर रहे हैं, तो निम्नलिखित का उपयोग करके ए XOR बी मूल्य की गणना जावास्क्रिप्ट में की जा सकती है
var xor1 = !(a === b);
पिछली पंक्ति भी निम्न के बराबर है
var xor2 = (!a !== !b);
व्यक्तिगत रूप से, मैं xor1 को पसंद करता हूं क्योंकि मुझे कम वर्ण टाइप करने हैं। मेरा मानना है कि xor1 भी तेज है। यह सिर्फ दो गणना कर रहा है। xor2 तीन गणना कर रहा है।
दृश्य स्पष्टीकरण ... तालिका बोला पढ़ें (जहां 0 झूठ के लिए खड़ा है और 1 सच के लिए खड़ा है) और 3 और 5 वें कॉलम की तुलना करें।
! (ए === बी):
| A | B | A XOR B | A === B | !(A === B) |
------------------------------------------
| 0 | 0 | 0 | 1 | 0 |
| 0 | 1 | 1 | 0 | 1 |
| 1 | 0 | 1 | 0 | 1 |
| 1 | 1 | 0 | 1 | 0 |
------------------------------------------
का आनंद लें।
var xor1 = !(a === b);
के रूप में ही हैvar xor1 = a !== b;
!(2 === 3)
है true
, लेकिन सत्य हैं 2
और ऐसा होना भी चाहिए । 3
2 XOR 3
false
चेक आउट:
आप इसे इस तरह से नकल कर सकते हैं:
if( ( foo && !bar ) || ( !foo && bar ) ) {
...
}
कैसे परिणाम बदलने के बारे में पूर्णांक एक को bool डबल निषेध के साथ? इतना सुंदर नहीं है, लेकिन वास्तव में कॉम्पैक्ट है।
var state1 = false,
state2 = true;
var A = state1 ^ state2; // will become 1
var B = !!(state1 ^ state2); // will become true
console.log(A);
console.log(B);
B = ((!state1)!==(!state2))
B =!!(!state1 ^ !state2);
भी, इतने सारे कोष्ठक क्यों? B = !state1 !== !state2;
या आप नकार को भी छोड़ सकते हैं:B = state1 !== state2;
state1 !== state2
, तो आपको वहां कोई कास्टिंग करने की आवश्यकता नहीं है, क्योंकि !==
एक तार्किक ऑपरेटर है, एक बिटवाइज़ नहीं। 12 !== 4
सच है सच 'xy' !== true
भी है। यदि आप !=
इसके बजाय उपयोग करते हैं !==
, तो आपको कास्टिंग करना होगा।
!==
और !=
हमेशा बूलियन है ... निश्चित नहीं है कि आप जो अंतर बना रहे हैं वह माना जाता है, यह समस्या नहीं है। समस्या यह है कि XOR ऑपरेटर जो हम चाहते हैं वह वास्तव में अभिव्यक्ति है (Boolean(state1) !== Boolean(state2))
। बूलियन्स के लिए, "xy", 12, 4 और true
सभी सत्य मूल्य हैं, और इन्हें परिवर्तित करना चाहिए true
। ऐसा ("xy" XOR true)
होना चाहिए false
, लेकिन ("xy" !== true)
इसके बजाय true
, जैसा कि आप बताते हैं। तो !==
या !=
(दोनों) "तार्किक XOR" के बराबर हैं यदि और केवल यदि आप आवेदन करने से पहले अपने तर्क को बूलियंस में बदल देते हैं ।
ऊपर दिए गए xor फ़ंक्शन में यह SIMILAR का परिणाम देगा क्योंकि तार्किक xor बिल्कुल तार्किक xor नहीं है, इसका अर्थ है कि यह "समान मूल्यों के लिए असत्य" और "अलग-अलग मूल्यों के लिए सत्य" के रूप में विचार में मिलान के साथ परिणाम देगा ।
यह XOR समारोह वास्तविक XOR या तार्किक ऑपरेटर के रूप में काम करेंगे , के लिए गुजर मान हैं यह सही या गलत के अनुसार परिणाम होगा साधन truthy या falsy । अपनी आवश्यकताओं के अनुसार उपयोग करें
function xor(x,y){return true==(!!x!==!!y);}
function xnor(x,y){return !xor(x,y);}
(!!x) === (!!y)
। अंतर बूलियन के लिए एक डाली है। '' === 0
असत्य है, जबकि xnor('', 0)
सत्य है।
टाइपस्क्रिप्ट में (संख्यात्मक मान में परिवर्तन):
value : number = (+false ^ +true)
इसलिए:
value : boolean = (+false ^ +true) == 1
!!(false ^ true)
साथ ठीक काम करता है। टाइपस्क्रिप्ट में, + इसे वैध बनाने के लिए आवश्यक है !!(+false ^ +true)
।
cond1 xor cond2
के बराबर है cond1 + cond 2 == 1
:
यहाँ सबूत है:
let ops = [[false, false],[false, true], [true, false], [true, true]];
function xor(cond1, cond2){
return cond1 + cond2 == 1;
}
for(op of ops){
console.log(`${op[0]} xor ${op[1]} is ${xor(op[0], op[1])}`)
}
कारण कोई तार्किक XOR (^ ^) नहीं है, क्योंकि && और || यह कोई आलसी-तर्क लाभ नहीं देता है। यह दाएं और बाएं दोनों अभिव्यक्तियों की स्थिति का मूल्यांकन करना है।
यहां एक वैकल्पिक समाधान है जो 2+ चर के साथ काम करता है और बोनस के रूप में गिनती प्रदान करता है।
यहाँ किसी भी सत्य / गलत मूल्यों के लिए तार्किक XOR का अनुकरण करने के लिए एक अधिक सामान्य समाधान है, जैसे कि यदि आप मानक में ऑपरेटर हैं तो आइए जानें:
const v1 = true;
const v2 = -1; // truthy (warning, as always)
const v3 = ""; // falsy
const v4 = 783; // truthy
const v5 = false;
if( ( !!v1 + !!v2 + !!v3 + !!v4 + !!v5 ) === 1 )
document.write( `[ ${v1} XOR ${v2} XOR "${v3}" XOR ${v4} XOR ${v5} ] is TRUE!` );
else
document.write( `[ ${v1} XOR ${v2} XOR "${v3}" XOR ${v4} XOR ${v5} ] is FALSE!` );
मुझे यह पसंद है, इसका कारण यह है कि यह भी जवाब देता है "इनमें से कितने चर सत्य हैं?", इसलिए मैं आमतौर पर उस परिणाम को प्री-स्टोर करता हूं।
और उन लोगों के लिए जो सख्त बूलियन-ट्रू एक्सर चेक व्यवहार चाहते हैं, बस:
if( ( ( v1===true ) + ( v2===true ) + ( v3===true ) + ( v4===true ) + ( v5===true ) ) === 1 )
// etc.
यदि आप गिनती के बारे में परवाह नहीं करते हैं, या यदि आप इष्टतम प्रदर्शन के बारे में परवाह करते हैं: तो बस सचाई / झूठे समाधान के लिए बूलियन के लिए मजबूर मूल्यों पर बिटवाइर एक्सर का उपयोग करें:
if( !!v1 ^ !!v2 ^ !!v3 ^ !!v4 ^ !!v5 )
// etc.
अरे मुझे यह समाधान मिला, बनाने के लिए और जावास्क्रिप्ट और टाइपस्क्रिप्ट पर XOR।
if( +!!a ^ +!!b )
{
//This happens only when a is true and b is false or a is false and b is true.
}
else
{
//This happens only when a is true and b is true or a is false and b is false
}
इस छोटे और आसान को समझने की कोशिश करो
function xor(x,y){return true==(x!==y);}
function xnor(x,y){return !xor(x,y);}
यह किसी भी डेटा प्रकार के लिए काम करेगा
true == someboolean
आवश्यक नहीं है, इसलिए वास्तव में, आपने जो किया है वह एक फ़ंक्शन में सख्त नहीं के बराबर लपेट रहा है।
!=
यह है कि आप ऐसा नहीं कर सकते हैंa ^= b
, क्योंकिa !== b
सिर्फ सख्त असमानता ऑपरेटर है।