Boole operatörleri && ve ||


252

Göre R dil tanımı arasındaki fark &ve &&(uygun |ve ||) ikinci değil ise eski vektörlü olmasıdır.

Göre yardım metni , ben Anlamı ... Bir "Ve" ve "AndAlso" (buna "Ya" ve "OrElse") arasındaki farka benzer bir fark okundu: tüm değerlendirmeler bunlar olmak zorunda yoksa o (yani A veya B veya C, A doğruysa her zaman doğrudur, bu nedenle A doğruysa değerlendirmeyi durdurun)

Birisi buraya ışık tutabilir mi? Ayrıca, R'de bir AndAlso ve OrElse var mı?


Benzer sorulara stackoverflow.com/q/6933598/210673 ve stackoverflow.com/q/7953833/210673 adresinden de bakın (artık kopya olarak kapalı).
Aaron Stack Overflow'dan ayrıldı

3
Bence && ve || Diğer dillerde, koşullu VE ve VEYA operatörleri mantıksal VE veya VEYA boole işlemleri gerçekleştirirler, ancak yalnızca gerekirse ikinci işlenenini değerlendirirler. R'de yararlı bir şey yapmayın.
skan

Yanıtlar:


340

Daha kısa olanları vektörize edilir, yani bir vektörü döndürebilirler, şöyle:

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

Uzun form soldan sağa her vektörün sadece ilk elemanını inceleyerek değerlendirir, böylece

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

Yardım sayfasının dediği gibi, bu daha uzun formu "kontrol akışını programlamak için uygun hale getirir ve eğer if maddelerinde tipik olarak tercih edilir".

Bu yüzden uzun formları sadece vektörlerin bir uzunluk olduğundan emin olduğunuzda kullanmak istersiniz.

Sen olmalıdır kesinlikle onlar dönüş sadece uzunluğu 1 mantıksal ifadenin fonksiyonlardır nerede vektörler gibi durumlarda sadece uzunluğu 1, olan belirli. Vektörlerin uzunluğu muhtemelen> 1 ise kısa formları kullanmak istersiniz. Bu yüzden kesinlikle emin değilseniz, önce kontrol etmeli veya kısa formu kullanmalı allve sonra anykontrol akış deyimlerinde kullanmak üzere bir uzunluğa azaltmak için ve tuşlarını kullanmalısınız if.

Fonksiyonlar allve anygenellikle karşılaştırmanın tamamının veya bir kısmının doğru olup olmadığını görmek için vectorized karşılaştırmanın sonucunda kullanılır. Bu işlevlerden elde edilen sonuçların uzunluk 1 olduğundan emin olun, bu nedenle if cümlelerinde kullanım için uygun olurken, vektörleştirilmiş karşılaştırmadan elde edilen sonuçlar değildir. (Bu sonuçlar, kullanım için uygun olsa da ifelse.

Son bir fark: &&ve ||sadece ihtiyaç duydukları kadar çok terimi değerlendirin (kısa devre ile kastedilen gibi). Örneğin, tanımsız bir değer kullanan bir karşılaştırma a; kısa devre, değil mi sanki &ve |yok, bu bir hata verecekti.

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

Son olarak, R Inferno'daki "ve ve ve" başlıklı bölüm 8.2.17'ye bakınız .


Uzunluk 1 mantıklarını karşılaştırıyorum. Belgelerin neden kontrol akışı için tercih edildiği konusunda net değil. Bu @ Theo cevaplarından "kısa devre" kullandığından ve böylece daha iyi performans var mı?
SFun28

Hayır. Sadece '&' kısa formunu kullanın - kısa devre cevapları yanlış.
M.Tibbits

1
Hayır, çünkü yalnızca tek bir DOĞRU / YANLIŞ yanıtı olmasını garanti eder. Daha kısa formlar ortaya çıkabilir c(TRUE, FALSE)ve ififade net olmaz. Her şeyin 1 uzunluğuna sahip olduğundan eminseniz, evet, ya da yaparsınız ve "kısa devre" nin birini tercih etmenin nedeni olduğu konusunda haklısınız. Ancak bir uyarı, sadece bir uzunluk olabileceğinden% 100 emin olduğunuzdan emin olun. Aksi takdirde gerçekten aptal böcek alabilirsiniz.
Aaron Stack Overflow'dan ayrıldı

9
@ SFun28: Evet, akış kontrolü için tercih ettiği kısa devre. Daha iyi performansın yanı sıra, tüm argümanları değerlendirmek istemeyebilirsiniz. Standart örnek, ?is.RR veya S-Plus çalıştırıp çalıştırmadığınızı kontrol etmek için verilmiştir . if(exists("is.R") && is.function(is.R) && is.R()). Eğer is.Ryoksa, is.function(is.R)bir hata atacağından değerlendirmek istemezsiniz . Aynı şekilde is.Rbir işlev değilse , onu sanki sanki sanki istemiyorsunuzdur.
Richie Cotton

2
R inferno'nun mevcut versiyonunda, ilgili bölüm şimdi 8.2.17 "ve ve"
Silverfish

34

"Kısa devre" ile ilgili cevap potansiyel olarak yanıltıcıdır, ancak bazı gerçekleri vardır (aşağıya bakınız). R / S dilinde &&ve ||sadece ilk argümandaki ilk öğeyi değerlendirin. Bir vektördeki veya listedeki diğer tüm öğeler, ilk değerlerden bağımsız olarak yok sayılır. Bu operatörler, if (cond) {} else{}yeni vektörler oluşturmaktan ziyade inşaat ile çalışmak ve program kontrolünü yönlendirmek üzere tasarlanmıştır. &Ve |operatörler vektörler üzerinde çalışmak üzere tasarlanmıştır, bu nedenle "paralel" olarak uygulanacaklardır. en uzun argüman. Karşılaştırmalar yapılmadan önce her iki vektör de değerlendirilmelidir. Vektörler aynı uzunlukta değilse, daha kısa argümanın geri dönüşümü gerçekleştirilir.

Bağımsız değişkenlere &&veya değişkenlere ||bakıldığında, arka arkaya soldan sağa değerlerden herhangi birinin belirleyici olması durumunda, değerlendirmelerin durdurulması ve son değerin döndürülmesi için "kısa devre" vardır.

> 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

Kısa devre yapmanın avantajı, yalnızca argümanların değerlendirilmesi uzun zaman aldığında ortaya çıkar. Bu, genellikle bağımsız değişkenlerin daha büyük nesneleri işleyen veya daha karmaşık matematiksel işlemlere sahip işlevler olması durumunda ortaya çıkar.


"kısa devre" Bana yeni bir terim, ama nitelendirerek cevap hakkında söylediklerine katılıyor geliyor bana &&ve ||.
Aaron Stack Overflow'dan ayrıldı

@DWin - uzunluk 1 mantıksalları üzerinde çalıştırma durumunda, eşdeğer değil mi? Belgelerin belirttiği gibi kontrol akışında neden tercih edildiklerini anlamaya çalışıyorum. Ayrıca, R'nin bir "kısa devre" yapısı var mı?
SFun28

Bunlar > 1
M.

2
Eğer argümanlar işlevse &&ve birincisi yanlışsa, ikincisinin değerlendirilmeyeceği doğrudur . Bu ikisi için de geçerli değil ya &da ifelseher iki argümanı da değerlendirecek.
IRTFM

Theo'nun kısa devre hakkındaki cevabı da öyle değil mi?
Aaron Stack Overflow'dan ayrıldı

25

&&ve ||"kısa devre" denilen şeydir. Bu, ilk işlenen ifadenin değerini belirlemek için yeterliyse ikinci işleneni değerlendirmeyecekleri anlamına gelir.

Örneğin, ilk işlenen &&yanlışsa ikinci ifadeyi değerlendirmenin bir anlamı yoktur, çünkü ifadenin değerini değiştiremez ( false && trueve false && falseikisi de yanlıştır). ||İlk işlenen doğru olduğunda da aynı şey geçerlidir.

Bununla ilgili daha fazla bilgiyi burada bulabilirsiniz: http://en.wikipedia.org/wiki/Short-circuit_evaluation Bu sayfadaki tablodan , bahsettiğinizi varsaydığım VB.NET'te &&eşdeğer olduğunu görebilirsiniz AndAlso.


3
Bu kısa devre olduğunu ispat yeterli olmalı: f <- function() { print('hello'); TRUE }; FALSE && f(). Değiştirin &ve işlevin değerlendirildiğine dikkat edin. QED.
Theo

2
Theo, evet, haklısın &&ve ||kısa devre. Ancak bu, kısa form ile uzun form arasındaki karşılaştırmalarda oldukça küçük bir nokta; girişler vektör olduğunda her birinin ne yaptığını anlamak çok daha önemlidir.
Aaron Stack Overflow'dan ayrıldı

2
@MTibbits Aslında bu tam bir cevap değil, ancak kısa devre ile ilgili ifade doğrudur . Deneyin F & {message("Boo!");T}ve F && {message("Boo!");T}.
mbq
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.