问题
I have a nested list called inputs
:
library(htmltools)
library(shiny)
inputs = tagList(
selectInput('first', 'FIRST', letters),
checkboxInput('second', 'SECOND')
)
str(inputs, max.level = 1)
List of 2
$ :List of 3
..- attr(*, "class")= chr "shiny.tag"
..- attr(*, "html_dependencies")=List of 1
$ :List of 3
..- attr(*, "class")= chr "shiny.tag"
- attr(*, "class")= chr [1:2] "shiny.tag.list" "list"
I would like to modify all sublists who have class shiny.tag
and whose name
element equals label
(see inputs[[1]][["children"]][[1]]
for an example of such a sublist) but preserve the original structure of the list while doing so.
To do this, I define a recursive function hideLabel
:
hideLabel <- function(tag.list) {
lapply(tag.list, function(x) {
if(inherits(x, 'shiny.tag')) {
if(x$name == 'label') {
tagAppendAttributes(x, style = 'display:none;')
} else {
hideLabel(x$children)
}
} else {
return(x)
}
})
}
Here is the output of applying hideLabel to the inputs list:
res = hideLabel(inputs)
str(res, max.level = 1)
List of 2
$ :List of 2
$ :List of 1
As shown above, hideLabel does not return a list of the same structure as the original list inputs (compare the output of str in the first code chunk with the output of str in the third chunk above). I was wondering if someone could help me understand why the function is doing this and how it could be modified? I have tried rewriting it several times to no avail.
Update:
I got it to work after thinking about what the function was returning at each stage. Here is the updated function:
hideLabel <- function(x) {
children = x$children
x$children = lapply(children, function(y) {
if(inherits(y, 'shiny.tag')) {
if(y$name == 'label') tagAppendAttributes(y, style = 'display:none;') else hil(y)
} else y
})
return(x)
}
This preserves the structure of the original list:
inputs_new = lapply(inputs, hideLabel)
str(inputs, max.level = 1)
List of 2
$ :List of 3
..- attr(*, "class")= chr "shiny.tag"
..- attr(*, "html_dependencies")=List of 1
$ :List of 3
..- attr(*, "class")= chr "shiny.tag"
- attr(*, "class")= chr [1:2] "shiny.tag.list" "list"
NOTE: The class of the overall list changes though from shiny.tag.list
to just list
. Would anyone know how to prevent this from happening? I know I could use do.call(tagList, inputs_new)
to manually add the shiny.tag.list
class back on but that seems hacky.
来源:https://stackoverflow.com/questions/58245155/apply-a-recursive-function-to-a-nested-list-while-preserving-the-classes-of-subl