基于属性值

时间:2018-05-09 21:18:51

标签: r list attributes

假设我有一个列表,其元素具有属性,如下所示:

my_list <- list()

my_list[[1]] <- 1:10
my_list[[2]] <- 11:20
my_list[[3]] <- 21:30

attr(my_list[[1]], "att1") <- "a"
attr(my_list[[2]], "att1") <- "b"
attr(my_list[[3]], "att1") <- "c"

attr(my_list[[1]], "att2") <- "1"
attr(my_list[[2]], "att2") <- "2"
attr(my_list[[3]], "att2") <- "3"

现在,假装这个列表长达数百个元素,我不知道列表中哪个元素具有我想要的属性。但我知道我想要这个元素,比如说att1 ==“b”和att2 ==“2”(但我不知道它恰好对应于列表元素2)。

在R中是否有办法查找列表中哪些元素具有特定的属性组合?

3 个答案:

答案 0 :(得分:8)

您可以使用Filter过滤列表:

Filter(function(x) attr(x, "att1") == "b" & attr(x, "att2") == "2", my_list)

如果您希望该元素是唯一的并且想要选择它,请在末尾添加[[1]]

就个人而言,我将数据放入表中:

library(data.table)
myDT = data.table(
  att1 = sapply(my_list, attr, "att1"), 
  att2 = sapply(my_list, attr, "att2"),
  data = my_list
)

#    att1 att2               data
# 1:    a    1       1,2,3,4,5,6,
# 2:    b    2 11,12,13,14,15,16,
# 3:    c    3 21,22,23,24,25,26,

然后你可以验证att1 + att2是否唯一地固定元素

nrow(myDT) == uniqueN(myDT, by=c("att1", "att2"))
# [1] TRUE

并为子集编写辅助函数

setkey(myDT, att1, att2)
get_element = function(a1, a2) myDT[.(a1, a2), data[[1]]]

get_element("b", "2")
#  [1] 11 12 13 14 15 16 17 18 19 20
# attr(,"att1")
# [1] "b"
# attr(,"att2")
# [1] "2"

您可能还想看一下purrr和扫帚包,这些包提供了不同的&#34; tidyverse&#34;具有列表列的表的语法。

答案 1 :(得分:4)

@Frank已经提供了一个很好的解决方案(答案背后有明确的逻辑)。我仍然想要涵盖其他几个选项(同样,在他的回答中已经由@Frank暗示过)。

选项#1:

library(purrr)
my_list %>% keep(~ attr(., "att1") == "b" & attr(., "att2") == "2")

#[[1]]
# [1] 11 12 13 14 15 16 17 18 19 20
#attr(,"att1")
#[1] "b"
#attr(,"att2")
#[1] "2"

选项#2:使用sapply

my_list[sapply(my_list, function(x)attr(x, "att1") == "b" & attr(x, "att2") == "2")]
# [[1]]
# [1] 11 12 13 14 15 16 17 18 19 20
# attr(,"att1")
# [1] "b"
# attr(,"att2")
# [1] "2"

答案 2 :(得分:2)

可能是这样的:

INIT_ONCE g_InitOnce = INIT_ONCE_STATIC_INIT;
A* g_AInstance = 0;  

BOOL CALLBACK MakeA(
    PINIT_ONCE InitOnce,       
    PVOID Parameter,           
    PVOID *lpContext)
{
    g_AInstance = new A(...);
    return TRUE;
}

class A
{
private:

public:
    static A& GetInstance() {
        // Execute the initialization callback function 
        bStatus = InitOnceExecuteOnce(&g_InitOnce,          
                            MakeA,   
                            NULL,                 
                            NULL);          
        assert(bStatus);
        return *g_AInstance;
    }
};        

具有多个属性的另一个解决方案:使用此代码对属性顺序没有约束。

ls_attr <- sapply(my_list, attributes)
ls_attr
#     [,1] [,2] [,3]
# att1 "a"  "b"  "c" 
# att2 "1"  "2"  "3"

my_list[ apply(ls_attr, 2, function(x) all( x %in% c('b', '2') )) ]
# [[1]]
# [1] 11 12 13 14 15 16 17 18 19 20
# attr(,"att1")
# [1] "b"
# attr(,"att2")
# [1] "2"