【发布时间】:2020-02-15 08:39:51
【问题描述】:
呸...即使尝试正确地框出标题也已经让我头疼了。
我有一个带有嵌套值的config.yml,我想定义一个索引函数get_config(),它接受“类路径”值字符串。
值字符串的“路径实体”匹配配置文件的嵌套实体结构。根据类似路径的值,该函数应该从配置文件中获取相应的层次结构实体(“分支”或“叶子”)。
示例
假设这是config.yml的结构:
default:
column_names:
col_id: "id"
col_value: "value"
column_orders:
data_structure_a: [
column_names/col_id,
column_names/col_value
]
data_structure_b: [
column_names/col_value,
column_names/col_id
]
这是一个解析后的版本供您使用:
x <- yaml::yaml.load(
'default:
column_names:
col_id: "id"
col_value: "value"
column_orders:
data_structure_a: [
column_names/col_id,
column_names/col_value
]
data_structure_b: [
column_names/col_value,
column_names/col_id
]'
)
使用config::get(value) 可以轻松访问顶级实体:
config::get("column_names")
# $col_id
# [1] "id"
#
# $col_value
# [1] "value"
config::get("column_orders")
# [1] "hello" "world"
但我也想访问更深层次的实体,例如column_names: col_id.
在伪代码中:
config::get("column_names:col_id")
或
config::get("column_orders/data_structure_a")
到目前为止我能想到的最好的:依靠unlist()
get_config <- function(value, sep = ":") {
if (value %>% stringr::str_detect(sep)) {
value <- value %>% stringr::str_replace(sep, ".")
configs <- config::get() %>% unlist()
configs[value]
} else {
config::get(value)
}
}
get_config("column_names")
# $col_id
# [1] "id"
#
# $col_value
# [1] "value"
get_config("column_names:col_id")
# column_names.col_id
# "id"
虽然不优雅,但它适用于大多数用例,但对于配置文件中的未命名列表实体失败
get_config("column_orders:data_structure_a")
# <NA>
# NA
因为我的索引方法与unlist() 在未命名列表上的结果不符:
config::get() %>% unlist()
# column_names.col_id column_names.col_value
# "id" "value"
# column_orders.data_structure_a1 column_orders.data_structure_a2
# "column_names/col_id" "column_names/col_value"
# column_orders.data_structure_b1 column_orders.data_structure_b2
# "column_names/col_value" "column_names/col_id"
因此,我想“递归”,但我的大脑说:“没办法,伙计”
尽职调查
This solution 接近(我猜)。
但我一直在想,我需要像 purrr::map2_if() 或 purrr::pmap_if()(不存在 AFAIK)而不是 purrr::map_if(),因为我不仅需要递归遍历 config::get() 后面的列表,而且value 的列表版本(例如通过stringr::str_split(value, sep) %>% unlist() %>% as.list())?
【问题讨论】:
标签: r recursion indexing purrr