如何获取所有列表元素的索引路径?
tree <- list(1:6,b=list(a=20:23,b=28),c=c("a","b"))
如何从现有列表树中获取所有叶子的寻址信息? 以向量列表的形式返回值,如下所示。
ret <- list(leaf1=c(1,1), .... ,leaf7=c(2,1,1), .... ,leaf13=c(3,2))
# tree[[c(2,1,1)]] should return 20 then.
# so the leaf7 value is indexing vector for tree$b$a[1] in another notation.
# so the tree$b$a[1] is same as tree[[ret$leaf7]]
# and so the object ret is then sort of a map of list "tree"
答案 0 :(得分:3)
您的基本深度优先搜索。 Map / unlist组合用于保持结果列表平坦,因此else子句的叶级结果必须包含在列表中。 idx
将当前索引保存到结构中,acc
是叶子的累积索引。
index.leaves <- function(root) {
walk <- function(node,idx,acc) {
if(length(node)>1) {
r<-Map(function(child,i) walk(child,c(idx,i),acc),node,seq_along(node))
unlist(r,recursive=FALSE)
}
else {
list(c(acc,idx))
}
}
walk(root,NULL,c())
}
使用样本数据
str(index.leaves(tree))
List of 13 $ : num [1:2] 1 1 $ : num [1:2] 1 2 $ : num [1:2] 1 3 $ : num [1:2] 1 4 $ : num [1:2] 1 5 $ : num [1:2] 1 6 $ b.a1: num [1:3] 2 1 1 $ b.a2: num [1:3] 2 1 2 $ b.a3: num [1:3] 2 1 3 $ b.a4: num [1:3] 2 1 4 $ b.b : num [1:2] 2 2 $ c.a : num [1:2] 3 1 $ c.b : num [1:2] 3 2
答案 1 :(得分:2)
一些递归方法,它们使用不同的方法来展平结果列表:
方法1 。深度优先搜索;一旦我们到达底部,将结果保存到上级变量L
。
nametree <- function(X) {
L <- NULL
rec <- function(X, prefix = NULL) {
if( length(X) == 1 ) {L <<- c(L,list(prefix)); return()}
sapply(seq_along(X), function(i) rec(X[[i]], c(prefix,i)))
}
rec(X)
L
}
方法2 。深度优先搜索;带索引的向量通过return
保存。在这种情况下,结果是嵌套列表,因此应该展平,这是通过rapply/unlist/split
组合实现的。
nametree2 <- function(X) {
rec <- function(X, prefix = NULL) {
if( length(X) == 1 ) return(prefix)
lapply(seq_along(X), function(i) rec(X[[i]], c(prefix,i)))
}
z <- rec(X)
# Convert nested list into a simple list
z2 <- rapply(z,length)
split(unlist(z),rep(seq_along(z2),z2))
}
z <- nametree(tree)
z2 <- nametree2(tree)
两种方法都返回相同的结果,可用于索引原始tree
列表:
> tree[[z[[7]]]]
[1] 20
> tree[[z2[[7]]]]
[1] 20