List filtering is to select list members that meet given criteria. In rlist package, more than ten functions are related with list filtering. Basically, they all perform a mapping but aggregate the results in different ways.
library(rlist)
devs <-
list(
p1=list(name="Ken",age=24,
interest=c("reading","music","movies"),
lang=list(r=2,csharp=4,python=3)),
p2=list(name="James",age=25,
interest=c("sports","music"),
lang=list(r=3,java=2,cpp=5)),
p3=list(name="Penny",age=24,
interest=c("movies","reading"),
lang=list(r=1,cpp=4,python=2)))
list.filter
filters a list by an expression that returns a logical value. Only the list members for which the value of that expression turns out to be TRUE
will be part of the results.
str(list.filter(devs, age >= 25))
# List of 1
# $ p2:List of 4
# ..$ name : chr "James"
# ..$ age : num 25
# ..$ interest: chr [1:2] "sports" "music"
# ..$ lang :List of 3
# .. ..$ r : num 3
# .. ..$ java: num 2
# .. ..$ cpp : num 5
str(list.filter(devs, "sports" %in% interest))
# List of 1
# $ p2:List of 4
# ..$ name : chr "James"
# ..$ age : num 25
# ..$ interest: chr [1:2] "sports" "music"
# ..$ lang :List of 3
# .. ..$ r : num 3
# .. ..$ java: num 2
# .. ..$ cpp : num 5
str(list.filter(devs, mean(as.numeric(lang)) >= 3))
# List of 2
# $ p1:List of 4
# ..$ name : chr "Ken"
# ..$ age : num 24
# ..$ interest: chr [1:3] "reading" "music" "movies"
# ..$ lang :List of 3
# .. ..$ r : num 2
# .. ..$ csharp: num 4
# .. ..$ python: num 3
# $ p2:List of 4
# ..$ name : chr "James"
# ..$ age : num 25
# ..$ interest: chr [1:2] "sports" "music"
# ..$ lang :List of 3
# .. ..$ r : num 3
# .. ..$ java: num 2
# .. ..$ cpp : num 5
Meta-symbols defined in lambda expression can also be used. The following code will pick up the list member whose index is even.
str(list.filter(devs, .i %% 2==0))
# List of 1
# $ p2:List of 4
# ..$ name : chr "James"
# ..$ age : num 25
# ..$ interest: chr [1:2] "sports" "music"
# ..$ lang :List of 3
# .. ..$ r : num 3
# .. ..$ java: num 2
# .. ..$ cpp : num 5
In some cases, we don't need to find all the results given the criteria. Rather, we only need to find a few, sometimes only one. list.find
will avoid searching across all list member but stops at a specific number of items found.
list.find(devs, age >= 25, 1)
# $p2
# $p2$name
# [1] "James"
#
# $p2$age
# [1] 25
#
# $p2$interest
# [1] "sports" "music"
#
# $p2$lang
# $p2$lang$r
# [1] 3
#
# $p2$lang$java
# [1] 2
#
# $p2$lang$cpp
# [1] 5
list.findi
only returns the index of the members found.
list.findi(devs, age >= 23, 2)
# [1] 1 2
list.takeWhile
keeps taking members while a condition holds true.
list.takeWhile(devs, lang$r >= 2)
# $p1
# $p1$name
# [1] "Ken"
#
# $p1$age
# [1] 24
#
# $p1$interest
# [1] "reading" "music" "movies"
#
# $p1$lang
# $p1$lang$r
# [1] 2
#
# $p1$lang$csharp
# [1] 4
#
# $p1$lang$python
# [1] 3
#
#
#
# $p2
# $p2$name
# [1] "James"
#
# $p2$age
# [1] 25
#
# $p2$interest
# [1] "sports" "music"
#
# $p2$lang
# $p2$lang$r
# [1] 3
#
# $p2$lang$java
# [1] 2
#
# $p2$lang$cpp
# [1] 5
list.skipWhile
keeps skipping members while a condition holds true.
list.skipWhile(devs, lang$r <= 2)
# $p2
# $p2$name
# [1] "James"
#
# $p2$age
# [1] 25
#
# $p2$interest
# [1] "sports" "music"
#
# $p2$lang
# $p2$lang$r
# [1] 3
#
# $p2$lang$java
# [1] 2
#
# $p2$lang$cpp
# [1] 5
#
#
#
# $p3
# $p3$name
# [1] "Penny"
#
# $p3$age
# [1] 24
#
# $p3$interest
# [1] "movies" "reading"
#
# $p3$lang
# $p3$lang$r
# [1] 1
#
# $p3$lang$cpp
# [1] 4
#
# $p3$lang$python
# [1] 2
list.is
returns a logical vector that indicates whether a condition holds for each member of a list.
list.is(devs, "music" %in% interest)
# p1 p2 p3
# TRUE TRUE FALSE
list.is(devs, "java" %in% names(lang))
# p1 p2 p3
# FALSE TRUE FALSE
list.is
returns a integer vector of the indices of the members of a list that meet a given condition.
list.which(devs, "music" %in% interest)
# [1] 1 2
list.which(devs, "java" %in% names(lang))
# [1] 2
list.all
returns TRUE
if all the members of a list satisfy a given condition, or FALSE
otherwise.
list.all(devs, mean(as.numeric(lang)) >= 3)
# [1] FALSE
list.all(devs, "r" %in% names(lang))
# [1] TRUE
list.any
returns TRUE
if at least one of the members of a list satisfies a given condition, or FALSE
otherwise.
list.any(devs, mean(as.numeric(lang)) >= 3)
# [1] TRUE
list.any(devs, "python" %in% names(lang))
# [1] TRUE
list.count
return a scalar integer that indicates the number of members of a list that satisfy a given condition.
list.count(devs, mean(as.numeric(lang)) >= 3)
# [1] 2
list.count(devs, "r" %in% names(lang))
# [1] 3
list.match
filters a list by matching the names of the list members by a regular expression pattern.
list.match(devs, "p[12]")
# $p1
# $p1$name
# [1] "Ken"
#
# $p1$age
# [1] 24
#
# $p1$interest
# [1] "reading" "music" "movies"
#
# $p1$lang
# $p1$lang$r
# [1] 2
#
# $p1$lang$csharp
# [1] 4
#
# $p1$lang$python
# [1] 3
#
#
#
# $p2
# $p2$name
# [1] "James"
#
# $p2$age
# [1] 25
#
# $p2$interest
# [1] "sports" "music"
#
# $p2$lang
# $p2$lang$r
# [1] 3
#
# $p2$lang$java
# [1] 2
#
# $p2$lang$cpp
# [1] 5
list.remove
removes list members by index or name.
list.remove(devs, c("p1","p2"))
# $p3
# $p3$name
# [1] "Penny"
#
# $p3$age
# [1] 24
#
# $p3$interest
# [1] "movies" "reading"
#
# $p3$lang
# $p3$lang$r
# [1] 1
#
# $p3$lang$cpp
# [1] 4
#
# $p3$lang$python
# [1] 2
list.remove(devs, c(2,3))
# $p1
# $p1$name
# [1] "Ken"
#
# $p1$age
# [1] 24
#
# $p1$interest
# [1] "reading" "music" "movies"
#
# $p1$lang
# $p1$lang$r
# [1] 2
#
# $p1$lang$csharp
# [1] 4
#
# $p1$lang$python
# [1] 3
list.exclude
removes list members that satisfy given condition.
list.exclude(devs, "sports" %in% interest)
# $p1
# $p1$name
# [1] "Ken"
#
# $p1$age
# [1] 24
#
# $p1$interest
# [1] "reading" "music" "movies"
#
# $p1$lang
# $p1$lang$r
# [1] 2
#
# $p1$lang$csharp
# [1] 4
#
# $p1$lang$python
# [1] 3
#
#
#
# $p3
# $p3$name
# [1] "Penny"
#
# $p3$age
# [1] 24
#
# $p3$interest
# [1] "movies" "reading"
#
# $p3$lang
# $p3$lang$r
# [1] 1
#
# $p3$lang$cpp
# [1] 4
#
# $p3$lang$python
# [1] 2
subset
is implemented for list object in a way that combines list.filter
and list.map
. This function basically filters a list while at the same time maps the qualified list member by an expression.
subset(devs,age>=24,name)
# $p1
# [1] "Ken"
#
# $p2
# [1] "James"
#
# $p3
# [1] "Penny"
subset(devs,"reading" %in% interest, sum(as.numeric(lang)))
# $p1
# [1] 9
#
# $p3
# [1] 7