List manipulation functions

lib.lists.singleton

singleton :: a -> [a]

Create a list consisting of a single element. singleton x is sometimes more convenient with respect to indentation than [x] when x spans multiple lines.

x

Function argument

lib.lists.singleton usage example

singleton "foo"
=> [ "foo" ]

lib.lists.forEach

forEach :: [a] -> (a -> b) -> [b]

Apply the function to each element in the list. Same as map, but arguments flipped.

xs

Function argument

f

Function argument

lib.lists.forEach usage example

forEach [ 1 2 ] (x:
toString x
)
=> [ "1" "2" ]

lib.lists.foldr

foldr :: (a -> b -> b) -> b -> [a] -> b

“right fold” a binary function op between successive elements of list with nul as the starting value, i.e., foldr op nul [x_1 x_2 ... x_n] == op x_1 (op x_2 ... (op x_n nul)).

op

Function argument

nul

Function argument

list

Function argument

lib.lists.foldr usage example

concat = foldr (a: b: a + b) "z"
concat [ "a" "b" "c" ]
=> "abcz"
# different types
strange = foldr (int: str: toString (int + 1) + str) "a"
strange [ 1 2 3 4 ]
=> "2345a"

lib.lists.fold

fold is an alias of foldr for historic reasons

lib.lists.foldl

foldl :: (b -> a -> b) -> b -> [a] -> b

“left fold”, like foldr, but from the left: foldl op nul [x_1 x_2 ... x_n] == op (... (op (op nul x_1) x_2) ... x_n).

op

Function argument

nul

Function argument

list

Function argument

lib.lists.foldl usage example

lconcat = foldl (a: b: a + b) "z"
lconcat [ "a" "b" "c" ]
=> "zabc"
# different types
lstrange = foldl (str: int: str + toString (int + 1)) "a"
lstrange [ 1 2 3 4 ]
=> "a2345"

lib.lists.foldl'

foldl' :: (b -> a -> b) -> b -> [a] -> b

Strict version of foldl.

The difference is that evaluation is forced upon access. Usually used with small whole results (in contrast with lazily-generated list or large lists where only a part is consumed.)

lib.lists.imap0

imap0 :: (int -> a -> b) -> [a] -> [b]

Map with index starting from 0

f

Function argument

list

Function argument

lib.lists.imap0 usage example

imap0 (i: v: "${v}-${toString i}") ["a" "b"]
=> [ "a-0" "b-1" ]

lib.lists.imap1

imap1 :: (int -> a -> b) -> [a] -> [b]

Map with index starting from 1

f

Function argument

list

Function argument

lib.lists.imap1 usage example

imap1 (i: v: "${v}-${toString i}") ["a" "b"]
=> [ "a-1" "b-2" ]

lib.lists.concatMap

concatMap :: (a -> [b]) -> [a] -> [b]

Map and concatenate the result.

lib.lists.concatMap usage example

concatMap (x: [x] ++ ["z"]) ["a" "b"]
=> [ "a" "z" "b" "z" ]

lib.lists.flatten

Flatten the argument into a single list; that is, nested lists are spliced into the top-level lists.

x

Function argument

lib.lists.flatten usage example

flatten [1 [2 [3] 4] 5]
=> [1 2 3 4 5]
flatten 1
=> [1]

lib.lists.remove

remove :: a -> [a] -> [a]

Remove elements equal to 'e' from a list. Useful for buildInputs.

e

Element to remove from the list

lib.lists.remove usage example

remove 3 [ 1 3 4 3 ]
=> [ 1 4 ]

lib.lists.findSingle

findSingle :: (a -> bool) -> a -> a -> [a] -> a

Find the sole element in the list matching the specified predicate, returns default if no such element exists, or multiple if there are multiple matching elements.

pred

Predicate

default

Default value to return if element was not found.

multiple

Default value to return if more than one element was found

list

Input list

lib.lists.findSingle usage example

findSingle (x: x == 3) "none" "multiple" [ 1 3 3 ]
=> "multiple"
findSingle (x: x == 3) "none" "multiple" [ 1 3 ]
=> 3
findSingle (x: x == 3) "none" "multiple" [ 1 9 ]
=> "none"

lib.lists.findFirst

findFirst :: (a -> bool) -> a -> [a] -> a

Find the first element in the list matching the specified predicate or return default if no such element exists.

pred

Predicate

default

Default value to return

list

Input list

lib.lists.findFirst usage example

findFirst (x: x > 3) 7 [ 1 6 4 ]
=> 6
findFirst (x: x > 9) 7 [ 1 6 4 ]
=> 7

lib.lists.any

any :: (a -> bool) -> [a] -> bool

Return true if function pred returns true for at least one element of list.

lib.lists.any usage example

any isString [ 1 "a" { } ]
=> true
any isString [ 1 { } ]
=> false

lib.lists.all

all :: (a -> bool) -> [a] -> bool

Return true if function pred returns true for all elements of list.

lib.lists.all usage example

all (x: x < 3) [ 1 2 ]
=> true
all (x: x < 3) [ 1 2 3 ]
=> false

lib.lists.count

count :: (a -> bool) -> [a] -> int

Count how many elements of list match the supplied predicate function.

pred

Predicate

lib.lists.count usage example

count (x: x == 3) [ 3 2 3 4 6 ]
=> 2

lib.lists.optional

optional :: bool -> a -> [a]

Return a singleton list or an empty list, depending on a boolean value. Useful when building lists with optional elements (e.g. `++ optional (system == "i686-linux") firefox').

cond

Function argument

elem

Function argument

lib.lists.optional usage example

optional true "foo"
=> [ "foo" ]
optional false "foo"
=> [ ]

lib.lists.optionals

optionals :: bool -> [a] -> [a]

Return a list or an empty list, depending on a boolean value.

cond

Condition

elems

List to return if condition is true

lib.lists.optionals usage example

optionals true [ 2 3 ]
=> [ 2 3 ]
optionals false [ 2 3 ]
=> [ ]

lib.lists.toList

If argument is a list, return it; else, wrap it in a singleton list. If you're using this, you should almost certainly reconsider if there isn't a more "well-typed" approach.

x

Function argument

lib.lists.toList usage example

toList [ 1 2 ]
=> [ 1 2 ]
toList "hi"
=> [ "hi "]

lib.lists.range

range :: int -> int -> [int]

Return a list of integers from first' up to and including last'.

first

First integer in the range

last

Last integer in the range

lib.lists.range usage example

range 2 4
=> [ 2 3 4 ]
range 3 2
=> [ ]

lib.lists.partition

(a -> bool) -> [a] -> { right :: [a], wrong :: [a] }

Splits the elements of a list in two lists, right and wrong, depending on the evaluation of a predicate.

lib.lists.partition usage example

partition (x: x > 2) [ 5 1 2 3 4 ]
=> { right = [ 5 3 4 ]; wrong = [ 1 2 ]; }

lib.lists.groupBy'

Splits the elements of a list into many lists, using the return value of a predicate. Predicate should return a string which becomes keys of attrset `groupBy' returns.

groupBy' allows to customise the combining function and initial value

op

Function argument

nul

Function argument

pred

Function argument

lst

Function argument

lib.lists.groupBy' usage example

groupBy (x: boolToString (x > 2)) [ 5 1 2 3 4 ]
=> { true = [ 5 3 4 ]; false = [ 1 2 ]; }
groupBy (x: x.name) [ {name = "icewm"; script = "icewm &";}
{name = "xfce";  script = "xfce4-session &";}
{name = "icewm"; script = "icewmbg &";}
{name = "mate";  script = "gnome-session &";}
]
=> { icewm = [ { name = "icewm"; script = "icewm &"; }
{ name = "icewm"; script = "icewmbg &"; } ];
mate  = [ { name = "mate";  script = "gnome-session &"; } ];
xfce  = [ { name = "xfce";  script = "xfce4-session &"; } ];
}

groupBy' builtins.add 0 (x: boolToString (x > 2)) [ 5 1 2 3 4 ]
=> { true = 12; false = 3; }

lib.lists.zipListsWith

zipListsWith :: (a -> b -> c) -> [a] -> [b] -> [c]

Merges two lists of the same size together. If the sizes aren't the same the merging stops at the shortest. How both lists are merged is defined by the first argument.

f

Function to zip elements of both lists

fst

First list

snd

Second list

lib.lists.zipListsWith usage example

zipListsWith (a: b: a + b) ["h" "l"] ["e" "o"]
=> ["he" "lo"]

lib.lists.zipLists

zipLists :: [a] -> [b] -> [{ fst :: a, snd :: b}]

Merges two lists of the same size together. If the sizes aren't the same the merging stops at the shortest.

lib.lists.zipLists usage example

zipLists [ 1 2 ] [ "a" "b" ]
=> [ { fst = 1; snd = "a"; } { fst = 2; snd = "b"; } ]

lib.lists.reverseList

reverseList :: [a] -> [a]

Reverse the order of the elements of a list.

xs

Function argument

lib.lists.reverseList usage example


reverseList [ "b" "o" "j" ]
=> [ "j" "o" "b" ]

lib.lists.listDfs

Depth-First Search (DFS) for lists list != [].

before a b == true means that b depends on a (there's an edge from b to a).

stopOnCycles

Function argument

before

Function argument

list

Function argument

lib.lists.listDfs usage example

listDfs true hasPrefix [ "/home/user" "other" "/" "/home" ]
== { minimal = "/";                  # minimal element
visited = [ "/home/user" ];     # seen elements (in reverse order)
rest    = [ "/home" "other" ];  # everything else
}

listDfs true hasPrefix [ "/home/user" "other" "/" "/home" "/" ]
== { cycle   = "/";                  # cycle encountered at this element
loops   = [ "/" ];              # and continues to these elements
visited = [ "/" "/home/user" ]; # elements leading to the cycle (in reverse order)
rest    = [ "/home" "other" ];  # everything else

lib.lists.toposort

Sort a list based on a partial ordering using DFS. This implementation is O(N^2), if your ordering is linear, use sort instead.

before a b == true means that b should be after a in the result.

before

Function argument

list

Function argument

lib.lists.toposort usage example


toposort hasPrefix [ "/home/user" "other" "/" "/home" ]
== { result = [ "/" "/home" "/home/user" "other" ]; }

toposort hasPrefix [ "/home/user" "other" "/" "/home" "/" ]
== { cycle = [ "/home/user" "/" "/" ]; # path leading to a cycle
loops = [ "/" ]; }                # loops back to these elements

toposort hasPrefix [ "other" "/home/user" "/home" "/" ]
== { result = [ "other" "/" "/home" "/home/user" ]; }

toposort (a: b: a < b) [ 3 2 1 ] == { result = [ 1 2 3 ]; }

lib.lists.sort

Sort a list based on a comparator function which compares two elements and returns true if the first argument is strictly below the second argument. The returned list is sorted in an increasing order. The implementation does a quick-sort.

lib.lists.sort usage example

sort (a: b: a < b) [ 5 3 7 ]
=> [ 3 5 7 ]

lib.lists.compareLists

Compare two lists element-by-element.

cmp

Function argument

a

Function argument

b

Function argument

lib.lists.compareLists usage example

compareLists compare [] []
=> 0
compareLists compare [] [ "a" ]
=> -1
compareLists compare [ "a" ] []
=> 1
compareLists compare [ "a" "b" ] [ "a" "c" ]
=> -1

lib.lists.naturalSort

Sort list using "Natural sorting". Numeric portions of strings are sorted in numeric order.

lst

Function argument

lib.lists.naturalSort usage example

naturalSort ["disk11" "disk8" "disk100" "disk9"]
=> ["disk8" "disk9" "disk11" "disk100"]
naturalSort ["10.46.133.149" "10.5.16.62" "10.54.16.25"]
=> ["10.5.16.62" "10.46.133.149" "10.54.16.25"]
naturalSort ["v0.2" "v0.15" "v0.0.9"]
=> [ "v0.0.9" "v0.2" "v0.15" ]

lib.lists.take

take :: int -> [a] -> [a]

Return the first (at most) N elements of a list.

count

Number of elements to take

lib.lists.take usage example

take 2 [ "a" "b" "c" "d" ]
=> [ "a" "b" ]
take 2 [ ]
=> [ ]

lib.lists.drop

drop :: int -> [a] -> [a]

Remove the first (at most) N elements of a list.

count

Number of elements to drop

list

Input list

lib.lists.drop usage example

drop 2 [ "a" "b" "c" "d" ]
=> [ "c" "d" ]
drop 2 [ ]
=> [ ]

lib.lists.sublist

sublist :: int -> int -> [a] -> [a]

Return a list consisting of at most count elements of list, starting at index start.

start

Index at which to start the sublist

count

Number of elements to take

list

Input list

lib.lists.sublist usage example

sublist 1 3 [ "a" "b" "c" "d" "e" ]
=> [ "b" "c" "d" ]
sublist 1 3 [ ]
=> [ ]

lib.lists.last

last :: [a] -> a

Return the last element of a list.

This function throws an error if the list is empty.

list

Function argument

lib.lists.last usage example

last [ 1 2 3 ]
=> 3

lib.lists.init

init :: [a] -> [a]

Return all elements but the last.

This function throws an error if the list is empty.

list

Function argument

lib.lists.init usage example

init [ 1 2 3 ]
=> [ 1 2 ]

lib.lists.crossLists

Return the image of the cross product of some lists by a function.

lib.lists.crossLists usage example

crossLists (x:y: "${toString x}${toString y}") [[1 2] [3 4]]
=> [ "13" "14" "23" "24" ]

lib.lists.unique

unique :: [a] -> [a]

Remove duplicate elements from the list. O(n^2) complexity.

lib.lists.unique usage example

unique [ 3 2 3 4 ]
=> [ 3 2 4 ]

lib.lists.intersectLists

Intersects list 'e' and another list. O(nm) complexity.

e

Function argument

lib.lists.intersectLists usage example

intersectLists [ 1 2 3 ] [ 6 3 2 ]
=> [ 3 2 ]

lib.lists.subtractLists

Subtracts list 'e' from another list. O(nm) complexity.

e

Function argument

lib.lists.subtractLists usage example

subtractLists [ 3 2 ] [ 1 2 3 4 5 3 ]
=> [ 1 4 5 ]

lib.lists.mutuallyExclusive

Test if two lists have no common element. It should be slightly more efficient than (intersectLists a b == [])

a

Function argument

b

Function argument