我有一个输入数据 struct ,它的叶子 node 是空列表,而父列表只包含子列表.相关信息最终出现在列表属性中,我必须将其提取出来.为此,我需要获得all个列表元素的索引位置,并使用这些坐标遍历列表.{rrapply}
一直在为有元素的列表工作,但我想不出如何获得没有非列表子元素的列表的位置.
下面是一个Reprex,显示了我得到{rrapply}
的部分,以及它遗漏的部分,以及最后我编写的一个非常老式的解决方案.所以我有一个解决方案,但我想看看我能不能得到{rrapply}
来做这件事,并理解为什么我不能让它做我想做的事情.
# stackoverflow_list-element-position-vector.R
library(rrapply)
library(purrr)
# A sample list
lst <-
list(
list(),
list(
list(),
list(),
list()
),
list(a=1:3
, list()
)
)
# Misses all of the empty lists, just the sublist with the name "a":
rrapply(lst,
f = \(x, .xpos) .xpos,
how="melt") |>
pluck("value") |>
str()
#> List of 1
#> $ : int [1:2] 3 1
#;; From: https://stackoverflow.com/a/76124073/1022967
#;; Misses the positions of the intermediate nodes, which I need too.
#;; i.e., misses lists at position 2 and 3.
rrapply(lst
, classes = "list"
, condition = \(x) length(x) == 0
, f = \(x) NA
, how="recurse") |>
rrapply(f = \(x, .xpos) .xpos
, how="melt") |>
pluck("value") |>
str()
#> List of 6
#> $ : int 1
#> $ : int [1:2] 2 1
#> $ : int [1:2] 2 2
#> $ : int [1:2] 2 3
#> $ : int [1:2] 3 1
#> $ : int [1:2] 3 2
#;; Take a list, return flat list of all of the positions of list
#;; elements.
#;; Real old-school technique...
listEltPos <- function(llst) {
work_lst <-
list(list(coord_vec = integer(0), comp = llst))
output_lst <-
list()
while (TRUE) {
if (length(work_lst) == 0) break
# Pop off head of work_lst
e <-
pluck(work_lst, 1)
work_lst <-
work_lst[-1]
# If element isn't a list, nothing more to process
if (class(e$comp) != "list") next
# If here, it is a list. If length is 0, return
if (length(e$comp) == 0) next
# Otherwise, it has entries. Find relative coordinate of the entry
# and add that to the output list and make a list element with that
# coordinate and the corresponding subelement.
subElementPositions <-
seq(length(e$comp))
for (i in subElementPositions) {
# Append local pos to the overall coordinate vector
newPosVec <-
c(e$coord_vec, i)
sub_e <-
pluck(e$comp, i)
# Add current new pos to the output queue
output_lst <-
append(output_lst, list(newPosVec))
# Append subelements and their updated positions to the work queue
work_lst <-
append(work_lst, list(list(coord_vec=newPosVec, comp=sub_e)))
}
rm(i)
}
output_lst
}
#;; This is what I am hoping for
listEltPos(lst) |>
str()
#> List of 8
#> $ : int 1
#> $ : int 2
#> $ : int 3
#> $ : int [1:2] 2 1
#> $ : int [1:2] 2 2
#> $ : int [1:2] 2 3
#> $ : int [1:2] 3 1
#> $ : int [1:2] 3 2
创建于2023-05-03年第reprex v2.0.2页