【发布时间】:2014-12-05 18:58:59
【问题描述】:
让我们有一个将列表转换为准 JSON 字符串的函数:
as.cypher.list = function(l){
dots = l
reserved = c("ID", "label")
properties = dots[!names(dots) %in% reserved]
properties = gsub("',", "', ", # adds spaces after commas
gsub('"', "'", # replaces " with '
gsub('"([^"]+)":', "\\1:", # removes " around key names
toJSON(rapply(properties, as.character)))))
label = if(is.null(dots[["label"]])) "" else paste0(":", dots[["label"]])
ID = if(is.null(dots[["ID"]])) NA_character_ else dots[["ID"]]
query = sprintf("%s%s", label, properties)
return(query)
}
例如:
as.cypher.list(list(label="AA", a=1, b="foo", name="bar"))
# [1] ":AA{a:'1', b:'foo', name:'bar'}"
现在让我们来:
query = "MATCH {n}, {ae} RETURN n"
nodes = list(n=list(label="AA", a=1, b="foo", name="bar"),
ae=list(label="BB", b=2))
如何将nodes 列表中的值替换为query,以便每个列表名称与query 中的子字符串匹配?替换后的最终理想结果是:
query
# [1] "MATCH (n:AA{a:'1', b:'foo', name:'bar'}), (ae:BB{b:'2'}) RETURN n"
我可以这样做:
add_param = function(nm, val){
query <<- gsub(paste0("{", nm, "}"),
paste0("(", nm, as.cypher.list(val),")"),
query, fixed = T)
}
Map(add_param, names(nodes), nodes)
# $n
# [1] "MATCH (n:AA{a:'1', b:'foo', name:'bar'}), {ae} RETURN n"
#
# $ae
# [1] "MATCH (n:AA{a:'1', b:'foo', name:'vser'}), (ae:BB{b:'2'}) RETURN n"
但是请注意<<- 的使用,这很尴尬。
在这种情况下如何使用Reduce()?
【问题讨论】:
-
你为什么不写一个
for循环呢?似乎更容易 -
想学习 MapReduce 风格。此外,应避免使用 for 循环。
-
绝对应该避免错误地使用 for 循环。在您的情况下,for 循环很好,因为您将只是循环
seq_along(nodes)并且只在循环内更新变量query,所以非常好。