読者です 読者をやめる 読者になる 読者になる

ネストしてるリストでもfoldできるようになったよー

R

わーい。

> fold(paste,"",list(letters,LETTERS))
[1] " a b c d e f g h i j k l m n o p q r s t u v w x y z A B C D E F G H I J K L M N O P Q R S T U V W X Y Z"
> fold(function(x,y){'+'(x,y)},0,list(1,2,list(3,4)))
[1] 10

定義はこんな感じにしてみた。listがリストだったら(表現があれすぎるw)、unlistしてる。recursive=FALSEがないと全部unlistしちゃう。

fold <- function(func,init,list){
  if(is.null(list)){
    return(init)
  }else if(is.list(list)){
    return(fold(func,init,unlist(list,recursive=FALSE)))
  }else{
    fold(func,func(init,car(list)),cdr(list))
  }
}

これとrapplyを組み合わせると、例えば条件にあったものだけの和とかが計算できる。リストがネストしていても大丈夫!!

> fold(function(x,y){'+'(x,y)},0,rapply(list(1:10,list(1:10,list(1:10))),function(x){ifelse(x%%2==0,x,0)},how="list"))
[1] 90

文字列の長さが3以上のものをpasteしてみるとか。

> fold(paste,"",rapply(list("hoge","fuga",list("fo")),function(x){ifelse(nchar(x)>3,x,"")},how="list"))
[1] " hoge fuga "

文字列の長さが3以上の個数をカウント。

> fold(function(x,y){'+'(x,y)},0,rapply(list("hoge","fuga",list("fo")),function(x){ifelse(nchar(x)>3,1,0)},how="list"))
[1] 2