Korzystanie if
, ifelse
oraz`if`
Istnieje kilka sposobów wykonywania instrukcji if w R. Rozwiązania optymalne dla golfa mogą się bardzo różnić.
Podstawy
if
sł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.
ifelse
jest 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ół else
nie 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
. if
Zwykle 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 if
nadal 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 if
i `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, ifelse
gdy 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
... else
instrukcja.
Jeśli chcesz tylko jednej wartości TRUE
, użyj if
.
Do wykonania dowolnego kodu `if`
i if
zwykle są takie same pod względem liczby bajtów; Polecam if
głównie dlatego, że jest łatwiejszy do odczytania.