List mapping is to evaluate an expression for each list member. It is the fundamental operation in rlist. Almost all functions in this pacakge that work with expressions are using mapping but in different ways. The following examples demonstrate several types of mapping.
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)))
The simplest way of mapping is provided by list.map
. Basically, it evaluates an expression for each list member.
The function makes it easier to query a list by putting all fields of the list member in mapping to the environment where the expression is evaluated. In other words, the expression is evaluated in the context of one list member each time.
For example, the following code maps each list member in devs
by expression age
. Therefore, it results in a list where each item becomes the value of that expression for each member of devs
.
list.map(devs, age)
# $p1
# [1] 24
#
# $p2
# [1] 25
#
# $p3
# [1] 24
Since the expression does not have to be a field name of the list member, we can evaluate whatever we want in the context of a list member.
The following code maps each list member to the sum of years of they use the programming languages they know.
list.map(devs, sum(as.numeric(lang)))
# $p1
# [1] 9
#
# $p2
# [1] 10
#
# $p3
# [1] 7
If we need more than one values for each member, we can evaluate a vector or list expression.
The following code maps each list member to a new list of his or her age and range of number of years using a programming language.
list.map(devs, list(age=age,range=range(as.numeric(lang))))
# $p1
# $p1$age
# [1] 24
#
# $p1$range
# [1] 2 4
#
#
# $p2
# $p2$age
# [1] 25
#
# $p2$range
# [1] 2 5
#
#
# $p3
# $p3$age
# [1] 24
#
# $p3$range
# [1] 1 4
If we want to get the mapping results as a vector rather than a list, we can use list.mapv
, which basically calls unlist
to the list resulted from list.map
.
list.mapv(devs, age)
# p1 p2 p3
# 24 25 24
list.mapv(devs, sum(as.numeric(lang)))
# p1 p2 p3
# 9 10 7
list.mapv(devs, range(as.numeric(lang)))
# p11 p12 p21 p22 p31 p32
# 2 4 2 5 1 4
In contrast to list.map
, list.select
provides an easier way to map each list member to a new list. This functions basically evaluates all given expressions and put the results into a list.
If a field name a list member is selected, its name will automatically preserved. If a list item evaluated from other expression is selected, we may better give it a name, or otherwise it will only have an index.
list.select(devs, name, age)
# $p1
# $p1$name
# [1] "Ken"
#
# $p1$age
# [1] 24
#
#
# $p2
# $p2$name
# [1] "James"
#
# $p2$age
# [1] 25
#
#
# $p3
# $p3$name
# [1] "Penny"
#
# $p3$age
# [1] 24
list.select(devs, name, age, nlang=length(lang))
# $p1
# $p1$name
# [1] "Ken"
#
# $p1$age
# [1] 24
#
# $p1$nlang
# [1] 3
#
#
# $p2
# $p2$name
# [1] "James"
#
# $p2$age
# [1] 25
#
# $p2$nlang
# [1] 3
#
#
# $p3
# $p3$name
# [1] "Penny"
#
# $p3$age
# [1] 24
#
# $p3$nlang
# [1] 3
Sometimes we don't really need the result of a mapping but its side effects. For example, if we only need to print out something about each list member, we don't need to carry on the output of mapping.
list.iter
performs iterations over a list and returns nothing.
list.iter(devs, cat(name,":",age,"\n"))
# Ken : 24
# James : 25
# Penny : 24