在嵌套列表中查找元素路径的最佳方法

问题描述 投票:0回答:1

查找嵌套列表中元素的路径的最佳方法是什么?或者至少是一个好方法,不需要手动挖掘

View
中的列表。 这是一个我已经可以处理的例子:

l1 <- list(x = list(a = "no_match", b = "test_noname", c ="test_noname"),
           y = list(a = "test_name"))

在其他包中寻找现成的解决方案后,我发现 这种方法(强烈受到

rlist::list.search
):

list_search <- function(l, f) {
  ulist <- unlist(l, recursive = TRUE, use.names = TRUE)
  match <- f(ulist)
  ulist[match]
}
list_search(l1, f = \(x) x == "test_noname")
          x.b           x.c 
"test_noname" "test_noname" 

这个效果很好,因为很容易理解名称“x.b” 这里可以翻译为这样的访问:

l1[["x"]][["b"]]
[1] "test_noname"
# Or
purrr::pluck(l1, "x", "b")
[1] "test_noname"

我可以通过省略最后一个元素来获得同一级别上的所有元素 等级指数:

l1[["x"]]
$a
[1] "no_match"

$b
[1] "test_noname"

$c
[1] "test_noname"

这通常是我的目标,因为我知道其中之一的价值观/名称 我想要访问的元素和其他类似的元素都放在 相同的子级别(或子子子子子子子子子子级别)。

然而,互联网上的许多 json 文件并不是很容易 消耗并解析成更复杂的列表,看起来更 像这样:

l2 <- list(x = list("no_match", list("test_noname1", "test_noname2")), y = list(a = "test_name"))
str(l2)
List of 2
 $ x:List of 2
  ..$ : chr "no_match"
  ..$ :List of 2
  .. ..$ : chr "test_noname1"
  .. ..$ : chr "test_noname2"
 $ y:List of 1
  ..$ a: chr "test_name"
list_search(l2, f = \(x) x == "test_noname")
named character(0)

从结果名称来看,我猜测元素“x2”可以是 像这样访问:

l2[["x"]]
[[1]]
[1] "no_match"

[[2]]
[[2]][[1]]
[1] "test_noname1"

[[2]][[2]]
[1] "test_noname2"
# or maybe
l2[["x"]][[1]]
[1] "no_match"

但为了不扫垃圾,这里用“no_match”表示,我 实际上需要这样的东西:

l2[["x"]][[2]][[2]]
[1] "test_noname2"

然后将其推广到下面的代码,以获得其他相关元素:

l2[["x"]][[2]]
[[1]]
[1] "test_noname1"

[[2]]
[1] "test_noname2"

所以问题本质上是列表中未命名的元素,而不是 分配的名称很容易通过

unlist
rapply
概括为 那很重要。理想情况下,会有一种自动方式将这些转换为
pluck
调用。

r list purrr
1个回答
0
投票

如果问题是如何获取给定单元格内容的路径,则使用同名包中的

rrapply

library(rrapply)

ix <- rrapply(l2, 
  condition = \(x, .xname) x == "test_noname1",
  f = \(x, .xpos) .xpos,
  how = "flatten")

unlist(ix)
## 11 12 13 
##  1  2  1 

l2[[unlist(ix)]]
## [1] "test_noname1"

library(purrr)
pluck(l2, !!!unlist(ix))
## [1] "test_noname1"

注意

问题输入

l2 <- list(x = list("no_match", list("test_noname1", "test_noname2")),
           y = list(a = "test_name"))
© www.soinside.com 2019 - 2024. All rights reserved.