【问题标题】:Dynamically assign value to deeply nested list为深度嵌套列表动态赋值
【发布时间】:2020-01-26 12:27:52
【问题描述】:

我有一个字符串向量,比如

> cc <- c("a", "b", "c")
> cc
[1] "a" "b" "c"

...我有一个结构如下的列表:

> ll <- list("a" = list("b" = list("c" = "hola")))
> ll
$a
$a$b
$a$b$c
[1] "hola"

使用cc 动态访问ll 的元素的最简单方法是什么,以便我可以重新分配列表的值而无需构建新列表?基本上,我想访问 reference ll$a$b$c,而不是它的价值。

对此进行硬编码,我们将使用如下语法:

ll[[cc[1]]][[cc[2]]][[cc[3]]] <- ... # or
ll[["a"]][["b"]][["c"]] <- ... # or
ll$a$b$c <- ...

...这让我觉得我想要一个applylapply,但它不仅仅是lapply(cc, ...),因为它不会递归地将选择应用于ll。相反,它会做类似的事情:

ll[c[1]] <- ...
ll[c[2]] <- ...
ll[c[3]] <- ...

所以我想我需要使用Reduce()。因为,本质上,我要做的是将函数应用于变量,然后将函数应用于结果,然后将函数应用于结果,等等:

temp <-   ll[[c[1]]]
temp <- temp[[c[2]]]
temp <- temp[[c[3]]]
...

但我也不确定这是否可行,因为我们没有在temp 中保存对ll[[c[1]]] 的引用,而是在保存它的值(第二行应该会引发错误)。

我感觉解决方案将涉及Reduce,将列表访问函数称为`[[`,也可能是do.call(),但我迷路了。有什么想法吗?

【问题讨论】:

  • 子集很容易:Reduce(function(l, i) l[[i]], cc, init = ll)。子集赋值是这里的问题,因为它结合了两个递归(向下查找元素,然后再次向上进行赋值)。

标签: r list recursion dynamic reflection


【解决方案1】:

只需使用:

ll[[cc]]
#[1] "hola"

这不是基本[[ 运算符的众所周知的用法,但在我看来,这正是您所追求的。

来自?"[[",“递归(类列表)对象”部分:

'[[' 可以递归地应用于列表,因此如果单个 索引‘i’是长度为‘p’的向量,‘alist[[i]]’等价于 'alist[[i1]]...[[ip]]' 提供除最终索引之外的所有内容 结果是一个列表。

当然你也可以用它来重新赋值:

ll[[cc]] <- "hello"
ll
#$a
#$a$b
#$a$b$c
#[1] "hello"

【讨论】:

  • 哇,好干净!谢谢!
猜你喜欢
  • 2017-05-11
  • 2017-04-20
  • 2012-12-01
  • 2016-03-28
  • 1970-01-01
  • 2019-04-03
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多