I am using R to work with a large JS object (using the library rjsonio). As such, I have a lot of nested lists, which are getting somewhat cumbersome to work with. I have a simplified example below. I am trying to work with this object by creating some form of ‘getter’ and ‘setter’ functions. After looking around, I have found a pretty nice ‘getter’ function that recurses through the object and returns the first matching label. This is especially great because it lends itself to chaining functions together. However, I can not figure out a way to get the same effect for a ‘setter’ function. Any thoughts on how to create a ‘setter’ function that can be chained together in a similar fashion?
#example, simplified, object
app = list(
1,
2,
d=list(a=123,
b=456,
list(
FirstKey=list(attr1='good stuff', attr2=12345),
SecondKey=list(attr1='also good stuff', attr2=4321)
)
)
)
#Return a function that returns the value
#associated with first label that matches 'name'
getByName <- function(name){
rmatch <- function(x) {
pos <- match(name, names(x))
if (!is.na(pos))
return(x[[pos]])
for (el in x) {
if (class(el) == "list") {
out <- Recall(el)
if (!is.null(out)) return(out)
}
}
}
rmatch
}
getFirstKey <- getByName("FirstKey")
getAttr1 <- getByName("attr1")
getAttr2 <- getByName("attr2")
#I like that I can chain these functions together
getAttr1(getFirstKey(app))
getAttr2(getFirstKey(app))
# I would like to be able to do something like this
# But this won't work
### getAttr1(getFirstKey(app)) <- 9876
# This does work,,, but I loose the ability to chain functions together
# Closure around a replacement function
setterKeyAttr <- function(keyName, attr){
function(x, value){
x$d[[3]][[keyName]][[attr]] <- value
x
}
}
`setFirstKeyAttr2<-` <- setterKeyAttr("FirstKey", "attr2")
setFirstKeyAttr2(app) <- 22222
#check the answer is correct
getAttr2(getFirstKey(app))
references: R decorator to change both input and output
http://r.789695.n4.nabble.com/How-to-get-a-specific-named-element-in-a-nested-list-td3037430.html