ここで独自の再帰関数を作成する必要があると思います。
2つのリストを受け取る関数、list1
およびlist2
。もしも:
list1[[name]]
存在するが存在しないlist2[[name]]
、使用list1[[name]]
;
list1[[name]]
存在するだけでなくlist2[[name]]
、両方ともリストではありませんlist2[[name]]
。;を使用してください。
- それ以外の場合は、新しいリスト
list1[[name]]
を使用して繰り返します。list2[[name]]
何かのようなもの:
myMerge <- function (list1, list2) {
allNames <- unique(c(names(list1), names(list2)))
merged <- list1 # we will copy over/replace values from list2 as necessary
for (x in allNames) {
# convenience
a <- list1[[x]]
b <- list2[[x]]
if (is.null(a)) {
# only exists in list2, copy over
merged[[x]] <- b
} else if (is.list(a) && is.list(b)) {
# recurse
merged[[x]] <- myMerge(a, b)
} else if (!is.null(b)) {
# replace the list1 value with the list2 value (if it exists)
merged[[x]] <- b
}
}
return(merged)
}
警告-マージするリストがおかしい場合、おかしな出力が得られる可能性があります。例えば:
a <- list( a=list(a=1, b=2), b=3 )
b <- list( a=2 )
次に、マージされたリストにはa=2, b=3
。これは、リストであっても、b$a
からの値がからの値をオーバーライドするためです(この場合に何が起こるかを指定していません)。ただし、これらの種類のケースを処理するように変更するのは簡単です。覚えておいてください-それがリストであるかどうかをテストし、エントリがリストに存在するかどうかを確認するために使用します。a$a
a$a
myMerge
is.list
is.null(myList$a)
a
myList
これが、以下を使用した「ベクトル化」バージョンsapply
です。
merge.lists <- function(a, b) {
a.names <- names(a)
b.names <- names(b)
m.names <- sort(unique(c(a.names, b.names)))
sapply(m.names, function(i) {
if (is.list(a[[i]]) & is.list(b[[i]])) merge.lists(a[[i]], b[[i]])
else if (i %in% b.names) b[[i]]
else a[[i]]
}, simplify = FALSE)
}