从 R 中的对象列表中删除元素的最佳方法是什么
What is the best way of removing an element from a list of objects in R
在参考 类 in R i 运行 玩的时候感觉不太好看。如果我有一个对象列表,是否有办法从该列表中删除不涉及查找其索引的单个项目?在下面的(工作)示例中,我想要一种更好的方法来实现 removeContent() ,即某种无需循环即可从列表中删除项目的方法。如果可能的话,我会尽量坚持使用 base R。
Element <- setRefClass(
Class ="Element",
fields = list(
m_name = "character",
contentList = "list"
),
methods = list(
initialize = function(name = NULL) {
"Element constructor, @param name, The name of the tag (optional)"
if(!is.null(name)) {
m_name <<- name
}
},
addContent = function(content) {
"Appends the child to the end of the content list. return the parent (the calling object)"
idx <- length(contentList) + 1
contentList[[idx]] <<- content
return(.self)
},
findContentIndex = function(content) {
"Find the position of the content in the contentList or -1 if not found"
for (idx in seq_along(contentList)) {
if(identical(content, contentList[[idx]])) {
return(idx)
}
}
-1
},
removeContent = function(content) {
"Remove the specified content from this element"
index <- findContentIndex(content)
if ( index != -1){
contentList <<- contentList[- index]
} else {
stop("There is no such content belonging to this Element")
}
}
)
)
foo <- Element$new("foo")
foo$addContent(Element$new("Bar"))
baz <- Element$new("Baz")
foo$addContent(baz)
foo$removeContent(baz)
tryCatch(
{
foo$removeContent(baz)
},
error=function(cond) {
print(paste("Expected this error, ", cond$message))
}
)
不使用显式索引的方法是使用 sapply(contentList, identical, content)
来查找匹配的对象。我们可以简化您的整个 class 定义,保留功能,如下所示:
Element <- setRefClass(
Class = "Element",
fields = list(m_name = "character", contentList = "list"),
methods = list(initialize = function(name = NULL)
{
if (!is.null(name)) m_name <<- name
},
addContent = function(content)
{
contentList <<- append(contentList, content)
},
removeContent = function(content)
{
idx <- sapply(contentList, identical, content)
if (all(!idx)) stop("Content not found")
contentList <<- contentList[!idx]
})
)
现在我们可以在您的示例中对其进行测试:
foo <- Element$new("foo")
foo$addContent(Element$new("Bar"))
baz <- Element$new("Baz")
foo$addContent(baz)
foo
#> Reference class object of class "Element"
#> Field "m_name":
#> [1] "foo"
#> Field "contentList":
#> [[1]]
#> Reference class object of class "Element"
#> Field "m_name":
#> [1] "Bar"
#> Field "contentList":
#> list()
#>
#> [[2]]
#> Reference class object of class "Element"
#> Field "m_name":
#> [1] "Baz"
#> Field "contentList":
#> list()
foo$removeContent(baz)
foo
#> Reference class object of class "Element"
#> Field "m_name":
#> [1] "foo"
#> Field "contentList":
#> [[1]]
#> Reference class object of class "Element"
#> Field "m_name":
#> [1] "Bar"
#> Field "contentList":
#> list()
和你的 tryCatch
:
tryCatch(
{
foo$removeContent(baz)
},
error=function(cond) {
print(paste("Expected this error, ", cond$message))
}
)
#> [1] "Expected this error, Content not found"
由 reprex package (v0.3.0)
于 2020-04-08 创建
在参考 类 in R i 运行 玩的时候感觉不太好看。如果我有一个对象列表,是否有办法从该列表中删除不涉及查找其索引的单个项目?在下面的(工作)示例中,我想要一种更好的方法来实现 removeContent() ,即某种无需循环即可从列表中删除项目的方法。如果可能的话,我会尽量坚持使用 base R。
Element <- setRefClass(
Class ="Element",
fields = list(
m_name = "character",
contentList = "list"
),
methods = list(
initialize = function(name = NULL) {
"Element constructor, @param name, The name of the tag (optional)"
if(!is.null(name)) {
m_name <<- name
}
},
addContent = function(content) {
"Appends the child to the end of the content list. return the parent (the calling object)"
idx <- length(contentList) + 1
contentList[[idx]] <<- content
return(.self)
},
findContentIndex = function(content) {
"Find the position of the content in the contentList or -1 if not found"
for (idx in seq_along(contentList)) {
if(identical(content, contentList[[idx]])) {
return(idx)
}
}
-1
},
removeContent = function(content) {
"Remove the specified content from this element"
index <- findContentIndex(content)
if ( index != -1){
contentList <<- contentList[- index]
} else {
stop("There is no such content belonging to this Element")
}
}
)
)
foo <- Element$new("foo")
foo$addContent(Element$new("Bar"))
baz <- Element$new("Baz")
foo$addContent(baz)
foo$removeContent(baz)
tryCatch(
{
foo$removeContent(baz)
},
error=function(cond) {
print(paste("Expected this error, ", cond$message))
}
)
不使用显式索引的方法是使用 sapply(contentList, identical, content)
来查找匹配的对象。我们可以简化您的整个 class 定义,保留功能,如下所示:
Element <- setRefClass(
Class = "Element",
fields = list(m_name = "character", contentList = "list"),
methods = list(initialize = function(name = NULL)
{
if (!is.null(name)) m_name <<- name
},
addContent = function(content)
{
contentList <<- append(contentList, content)
},
removeContent = function(content)
{
idx <- sapply(contentList, identical, content)
if (all(!idx)) stop("Content not found")
contentList <<- contentList[!idx]
})
)
现在我们可以在您的示例中对其进行测试:
foo <- Element$new("foo")
foo$addContent(Element$new("Bar"))
baz <- Element$new("Baz")
foo$addContent(baz)
foo
#> Reference class object of class "Element"
#> Field "m_name":
#> [1] "foo"
#> Field "contentList":
#> [[1]]
#> Reference class object of class "Element"
#> Field "m_name":
#> [1] "Bar"
#> Field "contentList":
#> list()
#>
#> [[2]]
#> Reference class object of class "Element"
#> Field "m_name":
#> [1] "Baz"
#> Field "contentList":
#> list()
foo$removeContent(baz)
foo
#> Reference class object of class "Element"
#> Field "m_name":
#> [1] "foo"
#> Field "contentList":
#> [[1]]
#> Reference class object of class "Element"
#> Field "m_name":
#> [1] "Bar"
#> Field "contentList":
#> list()
和你的 tryCatch
:
tryCatch(
{
foo$removeContent(baz)
},
error=function(cond) {
print(paste("Expected this error, ", cond$message))
}
)
#> [1] "Expected this error, Content not found"
由 reprex package (v0.3.0)
于 2020-04-08 创建