Korzystanie if, ifelseoraz`if`
Istnieje kilka sposobów wykonywania instrukcji if w R. Rozwiązania optymalne dla golfa mogą się bardzo różnić.
Podstawy
ifsłuży do sterowania przepływem. Nie jest wektoryzowany, tzn. Może oceniać tylko warunki długości 1. Wymaga else(opcjonalnie) zwrócenia innej wartości.
ifelsejest funkcją. Jest wektoryzowany i może zwracać wartości o dowolnej długości. Trzeci argument (wartość else) jest obowiązkowy. *
`if`jest funkcją o takiej samej składni jak ifelse. Nie jest wektoryzowany, żaden z argumentów zwrotnych nie jest obowiązkowy.
* Nie jest to technicznie obowiązkowe; ifelse(TRUE,x)działa dobrze, ale generuje błąd, jeśli trzeci argument jest pusty, a warunek zostanie oceniony FALSE. Można go bezpiecznie używać tylko wtedy, gdy masz pewność, że warunek jest zawsze TRUE, a jeśli tak, to dlaczego w ogóle zawracasz sobie głowę instrukcją if?
Przykłady
Wszystkie są równoważne:
if(x)y else z # 13 bytes
ifelse(x,y,z) # 13 bytes
`if`(x,y,z) # 11 bytes
Zauważ, że spacje wokół elsenie są wymagane, jeśli używasz ciągów bezpośrednio w kodzie:
if(x)"foo"else"bar" # 19 bytes
ifelse(x,"foo","bar") # 21 bytes
`if`(x,"foo","bar") # 19 bytes
Jak dotąd `if`wydaje się być zwycięzcą, o ile nie mamy wektoryzacji danych wejściowych. Ale co z przypadkami, w których nie dbamy o inny stan? Powiedzmy, że chcemy wykonać część kodu tylko wtedy, gdy jest to warunek TRUE. ifZwykle najlepszy jest tylko jeden wiersz kodu :
if(x)z=f(y) # 11 bytes
ifelse(x,z<-f(y),0) # 19 bytes
`if`(x,z<-f(y)) # 15 bytes
W przypadku wielu wierszy kodu ifnadal wygrywa:
if(x){z=f(y);a=g(y)} # 20 bytes
ifelse(x,{z=f(y);a=g(y)},0) # 27 bytes
`if`(x,{z=f(y);a=g(y)}) # 23 bytes
Istnieje również możliwość, gdzie należy dbać o stan innego, i gdzie chcemy wykonać dowolny kod zamiast zwracać wartość. W takich przypadkach ifi `if`są równoważne w liczbie bajtów.
if(x)a=b else z=b # 17 bytes
ifelse(x,a<-b,z<-b) # 19 bytes
`if`(x,a<-b,z<-b) # 17 bytes
if(x){z=y;a=b}else z=b # 22 bytes
ifelse(x,{z=y;a=b},z<-b) # 24 bytes
`if`(x,{z=y;a=b},z<-b) # 22 bytes
if(x)a=b else{z=b;a=y} # 22 bytes
ifelse(x,a<-b,{z=b;a=y}) # 24 bytes
`if`(x,a<-b,{z=b;a=y}) # 22 bytes
if(x){z=y;a=b}else{z=b;a=y} # 27 bytes
ifelse(x,{z=y;a=b},{z=b;a=y}) # 29 bytes
`if`(x,{z=y;a=b},{z=b;a=y}) # 27 bytes
Podsumowanie
Użyj, ifelsegdy wprowadzisz długość> 1.
Jeśli zwracasz prostą wartość zamiast wykonywania wielu wierszy kodu, użycie `if`funkcji jest prawdopodobnie krótsze niż pełna if... elseinstrukcja.
Jeśli chcesz tylko jednej wartości TRUE, użyj if.
Do wykonania dowolnego kodu `if`i ifzwykle są takie same pod względem liczby bajtów; Polecam ifgłównie dlatego, że jest łatwiejszy do odczytania.