Rで、リストにO(1)で要素を追加したいときにどうするかという話。
簡単なやり方として、こういうイディオムがある。
l <- list()
l <- c(l, list(1:3))
しかし、これはリストのコピーを作成するため、O(リストの長さ)の時間がかかってしまう。ちなみにappendを使ったとしても同様にO(リストの長さ)の時間がかかる。まぁリストの長さが短い時はこれでもいいのだけど、長いリストに要素を追加したいときは困る。
参考ページ: Append an object to a list in R in amortized constant time?
O(1)にするには、自分でデータ構造を作らなければならないようだ。以下Stack Overflowよりコードを引用。
まずこういう関数を作って
expandingList <- function(capacity = 10) {
buffer <- vector('list', capacity)
length <- 0
methods <- list()
methods$double.size <- function() {
buffer <<- c(buffer, vector('list', capacity))
capacity <<- capacity * 2
}
methods$add <- function(val) {
if(length == capacity) {
methods$double.size()
}
length <<- length + 1
buffer[[length]] <<- val
}
methods$as.list <- function() {
b <- buffer[0:length]
return(b)
}
methods
}
こうすれば
> l <- expandingList()
> l$add("hello")
> l$add("world")
> l$add(101)
> l$as.list()
[[1]]
[1] "hello"
[[2]]
[1] "world"
[[3]]
[1] 101
O(1)で要素を追加できる。
でもCRANを探せばこういうデータ構造が入ってるパッケージが既にありそう…。誰か知ってたら教えて下さい。