【发布时间】:2019-10-15 17:53:02
【问题描述】:
问题
我想这应该是一个常见问题,但我找不到解决方案:
让我们假设一个深度嵌套的列表,例如:
my_list <- list(
"first_node" = list(
"group_a" = list(
"E001" = 1:5,
"E002" = list(
"F001" = 6:10,
"F002" = 11:15
)
),
"group_b" = list(
"XY01" = list(
"Z1" = LETTERS[1:5],
"Z2" = LETTERS[6:10],
"Z3" = list(
"ZZ1" = LETTERS[1],
"ZZ2" = LETTERS[2],
"ZZ3" = LETTERS[3]
)
),
"YZ" = LETTERS[11:15]
),
"group_c" = list(
"QQQQ" = list(
"RRRR" = 200:300
)
)
),
"second_node" = list(
"group_d" = list(
"L1" = 99:101,
"L2" = 12
)
)
)
期望的输出
我想按名称检索元素,这些元素可能位于该列表中未知的深度级别。重要的是,我只想要那个特定的元素,它是孩子,而不是父母。
例如,在my_list 中搜索"XY01" 应该会得到:
XY01 = list(
"Z1" = LETTERS[1:5],
"Z2" = LETTERS[6:10],
"Z3" = list(
"ZZ1" = LETTERS[1],
"ZZ2" = LETTERS[2],
"ZZ3" = LETTERS[3]
)
)
> str(XY01)
List of 3
$ Z1: chr [1:5] "A" "B" "C" "D" ...
$ Z2: chr [1:5] "F" "G" "H" "I" ...
$ Z3:List of 3
..$ ZZ1: chr "A"
..$ ZZ2: chr "B"
..$ ZZ3: chr "C"
以前的尝试
最初我想使用rapply() 来完成这项工作,但似乎我无法在当前迭代中访问names()。我的第二次尝试是编写自定义递归函数:
recursive_extract <- function(haystack, needle){
lapply(names(haystack), function(x){
if (needle %in% names(haystack[[x]])) {
return(haystack[[needle]])
} else {
recursive_extract(haystack[[x]], needle)
}
}) %>% setNames(names(haystack))
}
...这似乎也有问题,因为lapply() 总是会返回相同的对象,即使返回了NULL,所以父结构也随之而来。
我一直在研究 purrr 和 rlist-packages 以获得方便的功能,但似乎它们中的大多数不支持递归 (?)。
奖金挑战
提取所需元素后,理想情况下,我希望选择返回多少子级别。例如:
desired_func(haystack, needle, get_depth = 1) 前面的例子会导致:
XY01 = list(
"Z1" = LETTERS[1:5],
"Z2" = LETTERS[6:10]
)
> str(XY01)
List of 2
$ Z1: chr [1:5] "A" "B" "C" "D" ...
$ Z2: chr [1:5] "F" "G" "H" "I" ...
非常感谢您的帮助! :)
【问题讨论】:
-
关于预期输出:如果在不同的地方有多个同名的元素,并且深度可能不同怎么办?或者如果孩子与父母同名;)
-
@akrun 我已经更新了所需的输出
-
@BerndKonfuzius 对,忘了提一下:单匹配就可以了,因为在我的特殊情况下,我可以保证所有名称都是唯一的。
标签: r nested-lists