बुलियन ऑपरेटर्स && और ||


252

के अनुसार आर भाषा परिभाषा , के बीच का अंतर &और &&(तदनुसार |और ||) है कि पूर्व, जबकि दूसरा नहीं है vectorized जाता है।

सहायता पाठ के अनुसार , मैंने अंतर को एक "और" और "AndAlso" (तदनुसार "या" और "OrElse") के अंतर के रूप में पढ़ा ... अर्थ: यदि नहीं होना है तो सभी मूल्यांकन नहीं (अर्थात A या B या C हमेशा सत्य है यदि A सत्य है, तो A के सत्य होने पर मूल्यांकन करना बंद करें)

क्या कोई यहां प्रकाश डाल सकता है? इसके अलावा, क्या आर में एक एंडो और ऑर्ले है?


इसके अलावा stackoverflow.com/q/6933598/210673 और stackoverflow.com/q/7953833/210673 (अब एक डुप्लिकेट के रूप में बंद) पर समान प्रश्न देखें ।
हारून ने

3
मुझे लगता है && और || आर। में बुरी तरह से कार्यान्वित किया जाता है। अन्य भाषाओं में वे सशर्त और OR ऑपरेटर हैं, वे एक तार्किक और या बूलियन ऑपरेशन करते हैं, लेकिन केवल आवश्यक होने पर इसके दूसरे ऑपरेंड का मूल्यांकन करते हैं। आर में कुछ भी उपयोगी नहीं है।
18

जवाबों:


340

छोटे लोगों को सदिश किया जाता है, जिसका अर्थ है कि वे एक सदिश राशि लौटा सकते हैं:

((-2:2) >= 0) & ((-2:2) <= 0)
# [1] FALSE FALSE  TRUE FALSE FALSE

प्रत्येक वेक्टर के केवल पहले तत्व की जांच करने के लिए लंबा फॉर्म बाएं से दाएं मूल्यांकन करता है, इसलिए उपरोक्त देता है

((-2:2) >= 0) && ((-2:2) <= 0)
# [1] FALSE

जैसा कि सहायता पृष्ठ कहता है, यह लंबे रूप को "प्रोग्रामिंग नियंत्रण-प्रवाह के लिए उपयुक्त बनाता है और [यदि क्लॉस में आम तौर पर पसंद किया जाता है] है।"

तो आप लंबे रूपों का उपयोग तभी करना चाहते हैं जब आप निश्चित हों कि वैक्टर की लंबाई एक है।

आपको पूरी तरह से निश्चित होना चाहिए कि आपके वैक्टर केवल लंबाई 1 हैं, ऐसे मामलों में जहां वे कार्य हैं जो केवल लंबाई 1 बूलियन्स लौटाते हैं। आप लघु रूपों का उपयोग करना चाहते हैं यदि वैक्टर संभवतः लंबाई> 1 है। तो अगर आप पूरी तरह से सुनिश्चित नहीं कर रहे हैं, या तो आप पहले की जाँच करें, या छोटे फार्म का उपयोग करें और उसके बाद का उपयोग करना चाहिए allऔर anyनियंत्रण प्रवाह बयान में उपयोग के लिए लंबाई एक करने के लिए इसे कम करने, जैसे if

कार्यों allऔर anyअक्सर एक सदिश तुलना के परिणाम पर उपयोग किया जाता है यह देखने के लिए कि क्या सभी या किसी भी तुलना क्रमशः सही हैं। इन फ़ंक्शंस के परिणाम निश्चित रूप से लंबाई 1 हैं, इसलिए यदि वे क्लॉस में उपयोग के लिए उपयुक्त हैं, जबकि सदिश तुलना से परिणाम नहीं हैं। (हालांकि उन परिणामों में उपयोग के लिए उपयुक्त होगा ifelse

एक अंतिम अंतर: &&और ||केवल उतने ही शब्दों का मूल्यांकन करते हैं, जितने की उन्हें जरूरत होती है (जो लगता है कि शॉर्ट-सर्कुलेटिंग का मतलब है)। उदाहरण के लिए, यहां एक अपरिभाषित मूल्य का उपयोग करके तुलना की जाती है a; यदि यह शॉर्ट-सर्किट नहीं है, जैसा कि &और |नहीं, तो यह एक त्रुटि देगा।

a
# Error: object 'a' not found
TRUE || a
# [1] TRUE
FALSE && a
# [1] FALSE
TRUE | a
# Error: object 'a' not found
FALSE & a
# Error: object 'a' not found

अंत में, द आर इनफर्नो में खंड 8.2.17 देखें , जिसका शीर्षक "and and and" है।


मैं लम्बाई की तार्किकता की तुलना कर रहा हूँ। 1. प्रलेखन स्पष्ट नहीं है कि इसका नियंत्रण-प्रवाह के लिए प्राथमिकता क्यों है। ऐसा इसलिए है क्योंकि यह @ थियो के उत्तरों से "शॉर्ट-सर्किट" का उपयोग करता है और इस तरह बेहतर प्रदर्शन होता है?
SFun28

नहीं। बस संक्षिप्त रूप 'और' का उपयोग करें - शॉर्ट-सर्किट उत्तर गलत हैं।
एम। टिबबिट्स

1
नहीं, क्योंकि यह केवल एक TRUE / FALSE उत्तर देने की गारंटी देता है। छोटे रूप में परिणाम हो सकता है c(TRUE, FALSE), और ifबयान स्पष्ट नहीं होगा। यदि आप निश्चित हैं कि हर चीज की लंबाई 1 है, तो हाँ, या तो करेंगे, और आप सही हैं कि "शॉर्ट-सर्किट" एक को प्राथमिकता देने का कारण है। चेतावनी का एक शब्द हालांकि, सुनिश्चित करें कि आप 100% सुनिश्चित हैं कि वे केवल एक लंबाई के हो सकते हैं। तुम सच में नासमझ कीड़े अन्यथा प्राप्त कर सकते हैं।
हारून ने

9
@ SFun28: हां, शॉर्ट-सर्कुलेटिंग वह कारण है जो इसे फ्लो कंट्रोल के लिए पसंद करता है। बेहतर प्रदर्शन के साथ-साथ, आप सभी तर्कों का मूल्यांकन नहीं करना चाहेंगे। यह ?is.Rजांचने के लिए कि क्या आप R या S-Plus चला रहे हैं , विहित उदाहरण दिया गया है । if(exists("is.R") && is.function(is.R) && is.R())। यदि is.Rमौजूद नहीं है, तो आप मूल्यांकन नहीं करना चाहते हैं is.function(is.R)क्योंकि यह एक त्रुटि फेंक देगा। इसी तरह यदि is.Rकोई फ़ंक्शन नहीं है, तो आप इसे कॉल नहीं करना चाहते हैं, हालांकि यह है।
रिची कॉटन

2
आर अवरो के वर्तमान संस्करण में, संबंधित अनुभाग अब 8.2.17 है "और andand"
सिल्वरफ़िश

34

"लघु-परिशोधन" के बारे में उत्तर संभावित रूप से भ्रामक है, लेकिन इसमें कुछ सच्चाई है (नीचे देखें)। आर / एस भाषा में, &&और ||केवल पहले तर्क में पहले तत्व का मूल्यांकन करें। वेक्टर या सूची के अन्य सभी तत्वों को पहले वाले मूल्य की परवाह किए बिना अनदेखा किया जाता है। उन ऑपरेटरों को if (cond) {} else{}नए वैक्टर के निर्माण के बजाय निर्माण के साथ काम करने और कार्यक्रम नियंत्रण को निर्देशित करने के लिए डिज़ाइन किया गया है .. &और |ऑपरेटरों को वैक्टर पर काम करने के लिए डिज़ाइन किया गया है, इसलिए उन्हें "समानांतर में" लागू किया जाएगा, इसलिए बोलने के लिए, लंबाई के साथ सबसे लंबा तर्क। तुलना करने से पहले दोनों वैक्टर का मूल्यांकन किया जाना चाहिए। यदि वैक्टर समान लंबाई नहीं हैं, तो छोटे तर्क का पुनर्चक्रण किया जाता है।

जब तर्कों का मूल्यांकन &&या ||मूल्यांकन किया जाता है, तो "शॉर्ट-सर्कुलेटिंग" होता है कि यदि उत्तराधिकार में बाएं से दाएं किसी भी मूल्य निर्धारक हैं, तो मूल्यांकन बंद हो जाता है और अंतिम मूल्य वापस आ जाता है।

> if( print(1) ) {print(2)} else {print(3)}
[1] 1
[1] 2
> if(FALSE && print(1) ) {print(2)} else {print(3)} # `print(1)` not evaluated
[1] 3
> if(TRUE && print(1) ) {print(2)} else {print(3)}
[1] 1
[1] 2
> if(TRUE && !print(1) ) {print(2)} else {print(3)}
[1] 1
[1] 3
> if(FALSE && !print(1) ) {print(2)} else {print(3)}
[1] 3

शॉर्ट-सर्कुलेटिंग का लाभ केवल तब दिखाई देगा जब तर्कों का मूल्यांकन करने में लंबा समय लगेगा। यह आमतौर पर तब होता है जब तर्क वे कार्य होते हैं जो या तो बड़ी वस्तुओं को संसाधित करते हैं या गणितीय कार्य होते हैं जो अधिक जटिल होते हैं।


"शार्ट-सर्किटिंग" मेरे लिए एक नया शब्द है, लेकिन मुझे ऐसा लगता है कि इसका वर्णन करने वाला उत्तर इस बात से सहमत है कि आप क्या कहते हैं &&और क्या कहते हैं ||
हारून ने

@ डब्लू - लंबाई 1 तार्किकों के संचालन के मामले में, वे बराबर हैं? मैं यह समझने की कोशिश कर रहा हूं कि प्रलेखन राज्यों के रूप में वे नियंत्रण-प्रवाह में क्यों पसंद किए जाते हैं। इसके अलावा, क्या आर में "शॉर्ट-सर्किट" का निर्माण होता है?
SFun28

वे लंबाई के वैक्टर के लिए समान नहीं हैं > 1
एम। टिबबिट्स

2
यह सच है कि यदि &&कार्य करने के लिए तर्क दिए गए हैं और पहला गलत है, तो दूसरे का मूल्यांकन नहीं किया जाएगा। यह दोनों के लिए सही नहीं है &या ifelseजो दोनों तर्कों का मूल्यांकन करेगा।
IRTFM

क्या यह नहीं है कि शॉर्ट-सर्कुलेटिंग के बारे में थियो का क्या कहना है?
हारून ने

25

&&और ||क्या कहा जाता है "शॉर्ट सर्किटिंग"। इसका मतलब है कि वे दूसरे ऑपरेंड का मूल्यांकन नहीं करेंगे यदि पहला ऑपरैंड अभिव्यक्ति के मूल्य को निर्धारित करने के लिए पर्याप्त है।

उदाहरण के लिए यदि पहला ऑपरेंड &&गलत है, तो दूसरे ऑपरेंड का मूल्यांकन करने का कोई मतलब नहीं है, क्योंकि यह अभिव्यक्ति के मूल्य को बदल नहीं सकता है ( false && trueऔर false && falseदोनों झूठे हैं)। वही ||तब जाता है जब पहला ऑपरेंड सच होता है।

आप इसके बारे में और अधिक यहां पढ़ सकते हैं: http://en.wikipedia.org/wiki/Short-circuit_evaluation उस पृष्ठ की तालिका से आप देख सकते हैं कि VB.NET में &&बराबर है AndAlso, जिसे मैं मानता हूं कि आप इसका उल्लेख कर रहे हैं।


3
यह सबूत पर्याप्त है कि यह कम सर्किटिंग है किया जाना चाहिए: f <- function() { print('hello'); TRUE }; FALSE && f()। बदलें &और देखें कि फ़ंक्शन का मूल्यांकन किया गया है। QED।
थियो

2
थियो, हां, आप सही हैं &&और ||शॉर्ट-सर्किट। लेकिन यह वास्तव में छोटे रूप और लंबे रूप के बीच तुलना में एक काफी मामूली बिंदु है; यह समझना अधिक महत्वपूर्ण है कि इनपुट वैक्टर होने पर प्रत्येक क्या करता है।
हारून ने

2
@MTibbits वास्तव में यह एक पूर्ण उत्तर नहीं है, लेकिन शॉर्ट सर्किटिंग के बारे में बयान सही है । प्रयत्नF & {message("Boo!");T} और F && {message("Boo!");T}
mbq
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.