Convenience functions for working with List
last : List a -> Maybe a
Extract the last element of a list.
last [ 1, 2, 3 ]
--> Just 3
last []
--> Nothing
init : List a -> Maybe (List a)
Return all elements of the list except the last one.
init [ 1, 2, 3 ]
--> Just [ 1, 2 ]
init []
--> Nothing
getAt : Basics.Int -> List a -> Maybe a
Returns Just
the element at the given index in the list,
or Nothing
if the index is out of range.
uncons : List a -> Maybe ( a, List a )
Decompose a list into its head and tail. If the list is empty, return Nothing
. Otherwise, return Just (x, xs)
, where x
is head and xs
is tail.
uncons [1,2,3]
--> Just (1, [2,3])
uncons []
--> Nothing
unconsLast : List a -> Maybe ( a, List a )
Decompose a list into its body and last element. If the list is empty, return Nothing
. Otherwise, return Just (x, xs)
, where x
is the last element and xs
is the body.
unconsLast [1,2,3]
--> Just (3, [1,2])
unconsLast []
--> Nothing
maximumBy : (a -> comparable) -> List a -> Maybe a
Find the first maximum element in a list using a comparable transformation
maximumWith : (a -> a -> Basics.Order) -> List a -> Maybe a
Find the first maximum element in a list using a comparison function
maximumWith compare []
--> Nothing
maximumWith
(\x y -> compare x.val y.val)
[{id=1, val=1}, {id=2, val=2}, {id=3,val=2}]
--> Just { id = 2, val = 2 }
minimumBy : (a -> comparable) -> List a -> Maybe a
Find the first minimum element in a list using a comparable transformation
minimumWith : (a -> a -> Basics.Order) -> List a -> Maybe a
Find the first minimum element in a list using a comparison function
minimumWith compare []
--> Nothing
minimumWith
(\x y -> compare x.val y.val)
[{id=1, val=2}, {id=2, val=1}, {id=3,val=1}]
--> Just { id = 2, val = 1 }
andMap : List a -> List (a -> b) -> List b
Map functions taking multiple arguments over multiple lists. Each list should be of the same length.
toIntFunctions : List (Float -> Int)
toIntFunctions =
[ round
, floor
, ceiling
, truncate
]
toIntFunctions
|> andMap [ -1.5, -1.5, -1.5, -1.5 ]
--> [ -1, -2, -1, -1 ]
math : List (Int -> Int)
math =
[ (+) 1
, (*) 2
, (*) 3 >> (+) 1
]
math
|> andMap [ 1, 2, 3 ]
--> [ 2, 4, 10 ]
andThen : (a -> List b) -> List a -> List b
Equivalent to concatMap
. For example, suppose you want to have a cartesian product of [1,2] and [3,4]:
[ 1, 2 ]
|> andThen
(\x ->
[ 3, 4 ]
|> andThen (\y -> [ ( x, y ) ])
)
--> [ ( 1, 3 ), ( 1, 4 ), ( 2, 3 ), ( 2, 4 ) ]
Now suppose we want to have a cartesian product between the first list and the second list and its doubles:
[ 1, 2 ]
|> andThen
(\x ->
[ 3, 4 ]
|> andThen
(\y ->
[ y, y * 2 ]
|> andThen (\z -> [ ( x, z ) ])
)
)
--> [ ( 1, 3 ), ( 1, 6 ), ( 1, 4 ), ( 1, 8 ), ( 2, 3 ), ( 2, 6 ), ( 2, 4 ), ( 2, 8 )]
Advanced functional programmers will recognize this as the implementation of bind operator (>>=) for lists from the Monad
typeclass.
reverseMap : (a -> b) -> List a -> List b
reverseMap f xs
gives the same result as List.reverse (List.map f xs)
,
but is tail-recursive and slightly more efficient.
reverseMap sqrt [ 1, 4, 9 ]
--> [ 3, 2, 1 ]
takeWhile : (a -> Basics.Bool) -> List a -> List a
Take elements in order as long as the predicate evaluates to True
dropWhile : (a -> Basics.Bool) -> List a -> List a
Drop elements in order as long as the predicate evaluates to True
unique : List a -> List a
Remove duplicate values, keeping the first instance of each element which appears more than once.
unique [ 0, 1, 1, 0, 1 ]
--> [ 0, 1 ]
uniqueBy : (a -> b) -> List a -> List a
Drop duplicates where what is considered to be a duplicate is the result of first applying the supplied function to the elements of the list.
allDifferent : List a -> Basics.Bool
Indicate if list has duplicate values.
allDifferent [ 0, 1, 1, 0, 1 ]
--> False
allDifferent [ 0, 1, 2]
--> True
allDifferentBy : (a -> b) -> List a -> Basics.Bool
Indicate if list has duplicate values when supplied function are applied on each values.
setIf : (a -> Basics.Bool) -> a -> List a -> List a
Replace all values that satisfy a predicate with a replacement value.
setAt : Basics.Int -> a -> List a -> List a
Set a value in a list by index. Return the original list if the index is out of range.
setAt 0 42 [ 1, 2, 3 ]
--> [ 42, 2, 3 ]
remove : a -> List a -> List a
Remove the first occurrence of a value from a list.
updateIf : (a -> Basics.Bool) -> (a -> a) -> List a -> List a
Replace all values that satisfy a predicate by calling an update function.
updateAt : Basics.Int -> (a -> a) -> List a -> List a
Replace a value at a specific index by calling an update function. Return the original list if the index is out of range.
updateAt 0 ((+) 1) [ 1, 2, 3 ]
--> [ 2, 2, 3 ]
See also updateIfIndex
.
updateIfIndex : (Basics.Int -> Basics.Bool) -> (a -> a) -> List a -> List a
Replace a value at an index that satisfies a predicate, by calling an update function.
updateIfIndex ((==) 2) ((+) 1) [ 1, 2, 3 ]
--> [ 1, 2, 4 ]
See also updateAt
.
removeAt : Basics.Int -> List a -> List a
Remove the element at an index from a list. Return the original list if the index is out of range.
removeAt 0 [ 1, 2, 3 ]
--> [ 2, 3 ]
See also removeIfIndex
.
removeIfIndex : (Basics.Int -> Basics.Bool) -> List a -> List a
Remove an element at an index that satisfies a predicate.
removeIfIndex ((==) 2) [ 1, 2, 3 ]
--> [ 1, 2 ]
See also removeAt
.
removeWhen : (a -> Basics.Bool) -> List a -> List a
Take a predicate and a list, and return a list that contains elements which fails to satisfy the predicate.
This is equivalent to List.filter (not << predicate) list
.
isEven : Int -> Bool
isEven i =
modBy 2 i == 0
removeWhen isEven [ 1, 2, 3, 4 ]
--> [ 1, 3 ]
swapAt : Basics.Int -> Basics.Int -> List a -> List a
Swap two values in a list by index. Return the original list if the index is out of range. If the same index is supplied twice the operation has no effect.
swapAt 1 2 [ 1, 2, 3 ]
--> [ 1, 3, 2 ]
stableSortWith : (a -> a -> Basics.Order) -> List a -> List a
Similar to List.sortWith, this sorts values with a custom comparison function. Unlike List.sortWith, this sort is guaranteed to be a stable sort. Note that List.sortWith is faster and is preferred if sort stability is not required.
intercalate : List a -> List (List a) -> List a
Take a list and a list of lists, insert that list between every list in the list of lists, concatenate the result. intercalate xs xss
is equivalent to concat (intersperse xs xss)
.
intercalate [ 0, 0 ] [ [ 1, 2 ], [ 3, 4 ], [ 5, 6 ] ]
--> [ 1, 2, 0, 0, 3, 4, 0, 0, 5, 6 ]
transpose : List (List a) -> List (List a)
Transpose rows and columns of the list of lists.
transpose [ [ 1, 2, 3 ], [ 4, 5, 6 ] ]
--> [ [ 1, 4 ], [ 2, 5 ], [ 3, 6 ] ]
transpose [ [ 10, 11 ], [ 20, 40 ], [ 30, 31, 32, 400 ] ]
--> [ [ 10, 20, 30 ], [ 11, 40, 31 ] ]
subsequences : List a -> List (List a)
Return the list of all subsequences of a list.
subsequences [ 1, 2, 3 ]
--> [ [], [ 1 ], [ 2 ], [ 1, 2 ], [ 3 ], [ 1, 3 ], [ 2, 3 ], [ 1, 2, 3 ] ]
permutations : List a -> List (List a)
Return the list of of all permutations of a list. The result is in lexicographic order.
permutations [ 1, 2, 3 ]
--> [ [ 1, 2, 3 ], [ 1, 3, 2 ], [ 2, 1, 3 ], [ 2, 3, 1 ], [ 3, 1, 2 ], [ 3, 2, 1 ] ]
interweave : List a -> List a -> List a
Return a list that contains elements from the two provided, in alternate order. If one list runs out of items, append the items from the remaining list.
interweave [ 1, 3 ] [ 2, 4 ]
--> [ 1, 2, 3, 4 ]
interweave [ 1, 3, 5, 7 ] [ 2, 4 ]
--> [ 1, 2, 3, 4, 5, 7 ]
interweave [ 4, 9, 16 ] [ 2, 3, 5, 7 ]
--> [ 4, 2, 9, 3, 16, 5, 7 ]
cartesianProduct : List (List a) -> List (List a)
Return the cartesian product of a list of lists. If one list is empty, the result is an empty list. If the list of lists is empty, the result is an empty singleton.
cartesianProduct [ [ 1, 2 ], [ 3, 4, 5 ], [ 6 ] ]
--> [ [ 1, 3, 6 ], [ 1, 4, 6 ], [ 1, 5, 6 ], [ 2, 3, 6 ], [ 2, 4, 6 ], [ 2, 5, 6 ] ]
cartesianProduct [ [ 1, 2 ] ]
--> [ [ 1 ], [ 2 ] ]
cartesianProduct [ [ 1, 2 ], [], [ 6 ] ]
--> []
cartesianProduct [ [] ]
--> []
cartesianProduct []
--> [ [] ]
uniquePairs : List a -> List ( a, a )
Return all ways to pair the elements of the list. (Essentially, enumerate the possible "handshakes.")
The order of the pair elements doesn't matter, so if (1,2)
is a returned pair,
we don't return (2,1)
.
In more mathematical terms these are 2-combinations without repetition.
uniquePairs [ 1, 2, 3, 4 ]
--> [ ( 1, 2 ), ( 1, 3 ), ( 1, 4 ), ( 2, 3 ), ( 2, 4 ), ( 3, 4 ) ]
In this example, everybody shakes hands with three other people.
foldl1 : (a -> a -> a) -> List a -> Maybe a
Variant of foldl
that has no starting value argument and treats the head of the list as its starting value. If the list is empty, return Nothing
.
foldl1 (-) [ 1, 2, 3, 4 ]
--> Just 2
foldl1 (++) [ "a", "b", "c" ]
--> Just "cba"
foldl1 min []
--> Nothing
Note: This function changed in a major way between version 7.0.0 and 8.0.0 of this package. The function foldl1
took in 7.0.0 was b -> a -> b
consistent with the Haskell implementation of foldl
, but now its a -> b -> b
, consistent with List.foldl
. This function behaves differently in a breaking way, even though its type signature is the same.
foldr1 : (a -> a -> a) -> List a -> Maybe a
Variant of foldr
that has no starting value argument and treats the last element of the list as its starting value. If the list is empty, return Nothing
.
foldr1 (-) [ 1, 2, 3, 4 ]
--> Just -2
foldr1 (++) [ "a", "b", "c" ]
--> Just "abc"
foldr1 min []
--> Nothing
indexedFoldl : (Basics.Int -> a -> b -> b) -> b -> List a -> b
Variant of foldl
that passes the index of the current element to the step function. indexedFoldl
is to List.foldl
as List.indexedMap
is to List.map
.
indexedFoldr : (Basics.Int -> a -> b -> b) -> b -> List a -> b
Variant of foldr
that passes the index of the current element to the step function. indexedFoldr
is to List.foldr
as List.indexedMap
is to List.map
.
A custom type used for stoppable folds.
stoppableFoldl : (a -> b -> Step b) -> b -> List a -> b
A foldl
that can stop early instead of traversing the whole list.
stoppableFoldl
(\n acc ->
if acc >= 50 then
Stop acc
else
Continue (n + acc)
)
0
(List.range 1 10000)
--> 55
scanl : (a -> b -> b) -> b -> List a -> List b
Reduce a list from the left, building up all of the intermediate results into a list.
scanl (+) 0 [ 1, 2, 3, 4 ]
--> [ 0, 1, 3, 6, 10 ]
scanl1 : (a -> a -> a) -> List a -> List a
scanl1
is a variant of scanl
that has no starting value argument.
Compare:
scanl (+) 0 [ 1, 2, 3 ]
--> [ 0, 1, 3, 6 ]
scanl1 (+) [ 1, 2, 3 ]
--> [ 1, 3, 6 ]
scanl (-) 0 [ 1, 2, 3 ]
--> [ 0, 1, 1, 2 ]
scanl1 (-) [ 1, 2, 3 ]
--> [ 1, 1, 2 ]
scanr : (a -> b -> b) -> b -> List a -> List b
scanr
is a right-to-left dual of scanl
. Note that:
head (scanr f z xs) == foldr f z xs
Examples:
scanr (+) 0 [ 1, 2, 3 ]
--> [ 6, 5, 3, 0 ]
scanr (-) 0 [ 1, 2, 3 ]
--> [ 2, -1, 3, 0 ]
scanr1 : (a -> a -> a) -> List a -> List a
scanr1
is a variant of scanr
that has no starting value argument.
scanr1 (+) [ 1, 2, 3 ]
--> [ 6, 5, 3 ]
scanr1 (-) [ 1, 2, 3 ]
--> [ 2, -1, 3 ]
mapAccuml : (a -> b -> ( a, c )) -> a -> List b -> ( a, List c )
The mapAccuml function behaves like a combination of map and foldl; it applies a function to each element of a list, passing an accumulating parameter from left to right, and returning a final value of this accumulator together with the new list.
mapAccuml f a0 [ x1, x2, x3 ] == ( a3, [ y1, y2, y3 ] )
-- x1 x2 x3
-- | | |
-- a0 -- f --- f --- f -> a3
-- | | |
-- y1 y2 y3
Add a running total to a list of numbers:
mapAccuml (\a x -> ( a + x, ( x, a + x ) )) 0 [ 2, 4, 8 ]
--> ( 14, [ ( 2, 2 ), ( 4, 6 ), ( 8, 14 ) ] )
Map number by multiplying with accumulated sum:
mapAccuml (\a x -> ( a + x, a * x )) 5 [ 2, 4, 8 ]
--> ( 19, [ 10, 28, 88 ] )
mapAccumr : (a -> b -> ( a, c )) -> a -> List b -> ( a, List c )
The mapAccumr function behaves like a combination of map and foldr; it applies a function to each element of a list, passing an accumulating parameter from right to left, and returning a final value of this accumulator together with the new list.
mapAccumr f a0 [ x1, x2, x3 ] == ( a3, [ y1, y2, y3 ] )
-- x1 x2 x3
-- | | |
-- a3 <- f --- f --- f -- a0
-- | | |
-- y1 y2 y3
Add a count of remaining elements:
mapAccumr (\a x -> ( a + 1, ( x, a ) )) 0 [ 2, 4, 8 ]
--> ( 3, [ ( 2, 2 ), ( 4, 1 ), ( 8, 0 ) ] )
Map number by multiplying with right-to-left accumulated sum:
mapAccumr (\a x -> ( a + x, a * x )) 5 [ 2, 4, 8 ]
--> ( 19, [ 34, 52, 40 ] )
unfoldr : (b -> Maybe ( a, b )) -> b -> List a
The unfoldr
function is "dual" to foldr
. foldr
reduces a list to a summary value, unfoldr
builds a list from a seed. The function takes a function and a starting element. It applies the function to the element. If the result is Just (a, b)
, a
is accumulated and the function is applied to b
. If the result is Nothing
, the list accumulated so far is returned.
subtractOneUntilZero : Int -> Maybe (Int, Int)
subtractOneUntilZero i =
if i /= 0 then
Just (i, i - 1)
else
Nothing
unfoldr subtractOneUntilZero 5
--> [ 5, 4, 3, 2, 1 ]
iterate : (a -> Maybe a) -> a -> List a
Returns a list of repeated applications of f
. If f
returns Nothing
the iteration will stop. If it returns Just y
then y
will be added to the
list and the iteration will continue with f y
.
collatz : Int -> Maybe Int
collatz n =
if n == 1 then
Nothing
else
Just <|
if modBy 2 n == 0 then
n // 2
else
3 * n + 1
iterate collatz 13
--> [13,40,20,10,5,16,8,4,2,1]
initialize : Basics.Int -> (Basics.Int -> a) -> List a
Initialize a list of some length with some function.
initialize n f
creates a list of length n
with the element at index i
initialized to the result of f i
.
cycle : Basics.Int -> List a -> List a
Creates a list of the given length whose elements are obtained by cycling through the elements of the given list. If the given list is empty, the resulting list will be empty.
cycle 6 [ 4, 7, 8 ]
--> [ 4, 7, 8, 4, 7, 8 ]
cycle 4 [ 'a', 'b', 'c' ]
--> [ 'a', 'b', 'c', 'a' ]
cycle 9001 []
--> []
cycle 2 [ 1, 2, 3, 4, 5 ]
--> [ 1, 2 ]
reverseRange : Basics.Int -> Basics.Int -> List Basics.Int
Create a list of numbers, every element decreasing by one.
You give the highest and lowest number that should be in the list.
More efficient than calling List.reverse (List.range lo hi)
range 6 3 == [ 6, 5, 4, 3 ]
range 3 3 == [ 3 ]
range 3 6 == []
splitAt : Basics.Int -> List a -> ( List a, List a )
Take a number and a list, return a tuple of lists, where first part is prefix of the list of length equal the number, and second part is the remainder of the list. splitAt n xs
is equivalent to (take n xs, drop n xs)
.
splitAt 3 [ 1, 2, 3, 4, 5 ]
--> ( [ 1, 2, 3 ], [ 4, 5 ] )
splitAt 1 [ 1, 2, 3 ]
--> ( [ 1 ], [ 2, 3 ] )
splitAt 3 [ 1, 2, 3 ]
--> ( [ 1, 2, 3 ], [] )
splitAt 4 [ 1, 2, 3 ]
--> ( [ 1, 2, 3 ], [] )
splitAt 0 [ 1, 2, 3 ]
--> ( [], [ 1, 2, 3 ] )
splitAt -1 [ 1, 2, 3 ]
--> ( [], [ 1, 2, 3 ] )
splitWhen : (a -> Basics.Bool) -> List a -> Maybe ( List a, List a )
Attempts to split the list at the first element where the given predicate is true. If the predicate is not true for any elements in the list, return nothing. Otherwise, return the split list.
splitWhen (\n -> n == 3) [ 1, 2, 3, 4, 5 ]
--> Just ( [ 1, 2 ], [ 3, 4, 5 ] )
splitWhen (\n -> n == 6) [ 1, 2, 3, 4, 5 ]
--> Nothing
takeWhileRight : (a -> Basics.Bool) -> List a -> List a
Take elements from the right, while predicate still holds.
takeWhileRight ((<) 5) (List.range 1 10)
--> [ 6, 7, 8, 9, 10 ]
dropWhileRight : (a -> Basics.Bool) -> List a -> List a
Drop elements from the right, while predicate still holds.
dropWhileRight ((<) 5) (List.range 1 10)
--> [ 1, 2, 3, 4, 5 ]
span : (a -> Basics.Bool) -> List a -> ( List a, List a )
Take a predicate and a list, return a tuple. The first part of the tuple is the longest prefix of that list, for each element of which the predicate holds. The second part of the tuple is the remainder of the list. span p xs
is equivalent to (takeWhile p xs, dropWhile p xs)
.
span ((>) 3) [ 1, 2, 3, 4, 1, 2, 3, 4 ]
--> ( [ 1, 2 ], [ 3, 4, 1, 2, 3, 4 ] )
span ((>) 5) [ 1, 2, 3 ]
--> ( [ 1, 2, 3 ], [] )
span ((>) 0) [ 1, 2, 3 ]
--> ( [], [ 1, 2, 3 ] )
break : (a -> Basics.Bool) -> List a -> ( List a, List a )
Take a predicate and a list, return a tuple. The first part of the tuple is the longest prefix of that list, for each element of which the predicate does not hold. The second part of the tuple is the remainder of the list. break p xs
is equivalent to (takeWhile (not p) xs, dropWhile (not p) xs)
.
break ((<) 3) [ 1, 2, 3, 4, 1, 2, 3, 4 ]
--> ( [ 1, 2, 3 ], [ 4, 1, 2, 3, 4 ] )
break ((>) 5) [ 1, 2, 3 ]
--> ( [], [ 1, 2, 3 ] )
break ((<) 5) [ 1, 2, 3 ]
--> ( [ 1, 2, 3 ], [] )
stripPrefix : List a -> List a -> Maybe (List a)
Drop the given prefix from the list. If the list doesn't start with that prefix, return Nothing
.
stripPrefix [ 1, 2 ] [ 1, 2, 3, 4 ]
--> Just [ 3, 4 ]
stripPrefix [ 1, 2, 3 ] [ 1, 2, 3, 4, 5 ]
--> Just [ 4, 5 ]
stripPrefix [ 1, 2, 3 ] [ 1, 2, 3 ]
--> Just []
stripPrefix [ 1, 2, 3 ] [ 1, 2 ]
--> Nothing
stripPrefix [ 3, 2, 1 ] [ 1, 2, 3, 4, 5 ]
--> Nothing
group : List a -> List ( a, List a )
Group similar elements together. group
is equivalent to groupWhile (==)
.
group [ 1, 2, 2, 3, 3, 3, 2, 2, 1 ]
--> [ (1, []), (2, [ 2 ]), (3, [ 3, 3 ]), (2, [ 2 ]), ( 1, []) ]
groupWhile : (a -> a -> Basics.Bool) -> List a -> List ( a, List a )
Group elements together, using a custom comparison test (a -> a -> Bool
). Start a new group each time the comparison test doesn't hold for two adjacent elements.
groupWhile
uses a non-empty list type (a, List a)
since groups necessarily must have at least one member since they are determined by comparing two members.
groupWhile
(==)
[ 1, 2, 3 ]
--> [ ( 1, [] ), ( 2, [] ), ( 3, [] ) ]
groupWhile
(<)
[ 1, 2, 3, 2, 4, 1, 3, 2, 1 ]
--> [ ( 1, [ 2, 3 ] ), ( 2, [ 4 ] ), ( 1, [ 3 ] ), ( 2, [] ), ( 1, [] ) ]
groupWhile
(\a b -> a.id == b.id)
[ { value = 4, id = 9 }, { value = 7, id = 2 }, { value = 1, id = 2 } ]
--> [ ( { value = 4, id = 9 }, [] ), ( { value = 7, id = 2 }, [ { value = 1, id = 2 } ] ) ]
Note:
The behavior of this function has changed between major versions 7 and 8. In version 7 there was groupWhile
and groupWhileTransitively
. The behavior of the two was almost identical, however the transitive function was closer to what users found intuitive about grouping. groupWhileTransitively
has been deleted, and groupWhile
has been replaced with the version 7s groupWhileTransitively
behavior. Furthermore the group type was changed from List a
to the non-empty list type (a, List a)
. Sorry for any inconvenience this may cause.
inits : List a -> List (List a)
Return all initial segments of a list, from shortest to longest, empty list first, the list itself last.
inits [ 1, 2, 3 ]
--> [ [], [ 1 ], [ 1, 2 ], [ 1, 2, 3 ] ]
tails : List a -> List (List a)
Return all final segments of a list, from longest to shortest, the list itself first, empty list last.
tails [ 1, 2, 3 ]
--> [ [ 1, 2, 3 ], [ 2, 3 ], [ 3 ], [] ]
select : List a -> List ( a, List a )
Return all combinations in the form of (element, rest of the list). Read Haskell Libraries proposal for further ideas on how to use this function.
select [ 1, 2, 3, 4 ]
--> [ ( 1, [ 2, 3, 4 ] ), ( 2, [ 1, 3, 4 ] ), ( 3, [ 1, 2, 4 ] ), ( 4, [ 1, 2, 3 ] ) ]
selectSplit : List a -> List ( List a, a, List a )
Return all combinations in the form of (elements before, element, elements after).
selectSplit [ 1, 2, 3 ]
--> [ ( [], 1, [ 2, 3 ] ), ( [ 1 ], 2, [ 3 ] ), ( [ 1, 2 ], 3, [] ) ]
gatherEquals : List a -> List ( a, List a )
Group equal elements together. This is different from group
as each sublist
will contain all equal elements of the original list. Elements will be grouped
in the same order as they appear in the original list. The same applies to elements
within each group.
gatherEquals [1,2,1,3,2]
--> [(1,[1]),(2,[2]),(3,[])]
gatherEqualsBy : (a -> b) -> List a -> List ( a, List a )
Group equal elements together. A function is applied to each element of the list and then the equality check is performed against the results of that function evaluation. Elements will be grouped in the same order as they appear in the original list. The same applies to elements within each group.
gatherEqualsBy .age [{age=25},{age=23},{age=25}]
--> [({age=25},[{age=25}]),({age=23},[])]
See also: Dict.Extra.groupBy
.
gatherWith : (a -> a -> Basics.Bool) -> List a -> List ( a, List a )
Group equal elements together using a custom equality function. Elements will be grouped in the same order as they appear in the original list. The same applies to elements within each group.
gatherWith (==) [1,2,1,3,2]
--> [(1,[1]),(2,[2]),(3,[])]
subsequencesNonEmpty : List a -> List ( a, List a )
Return the list of all subsequences of the argument, except for the empty list.
subsequencesNonEmpty [ 1, 2, 3 ]
== [ [ 1 ], [ 2 ], [ 1, 2 ], [ 3 ], [ 1, 3 ], [ 2, 3 ], [ 1, 2, 3 ] ]
frequencies : List comparable -> List ( comparable, Basics.Int )
Calculate the number of occurences for each element in a list. Elements will be ordered ascendingly, then grouped in a tuple with the number of occurences.
frequencies [2,1,3,2,3,3]
--> [(1,1),(2,2),(3,3)]
isPrefixOf : List a -> List a -> Basics.Bool
Take two lists and return True
, if the first list is the prefix of the second list.
isSuffixOf : List a -> List a -> Basics.Bool
Take two lists and return True
, if the first list is the suffix of the second list.
isInfixOf : List a -> List a -> Basics.Bool
Return True if all the elements of the first list occur in-order and consecutively anywhere within the second.
isInfixOf [ 5, 7, 11 ] [ 2, 3, 5, 7, 11, 13 ]
--> True
isInfixOf [ 5, 7, 13 ] [ 2, 3, 5, 7, 11, 13 ]
--> False
isInfixOf [ 3, 5, 2 ] [ 2, 3, 5, 7, 11, 13 ]
--> False
isSubsequenceOf : List a -> List a -> Basics.Bool
Return True if all the elements of the first list occur, in order, in the second. The elements do not have to occur consecutively.
isSubsequenceOf
[ "E", "l", "m" ]
[ "E", "a", "t", " ", "l", "i", "m", "e", "s" ]
--> True
isSubsequenceOf
[ "E", "l", "m" ]
[ "E", "m", "a", "i", "l" ]
--> False
isPermutationOf : List a -> List a -> Basics.Bool
Take two lists and return True
, if the first list is a permutation of the second list.
In other words: Do the 2 List
s contain the same elements but in a different order?
[ 3, 1, 2 ]
|> isPermutationOf
[ 1, 2, 3 ]
--> True
[ 3, 1, 0 ]
|> isPermutationOf
[ 1, 2, 3 ]
--> False
[ 3, 1, 2, 2 ]
|> isPermutationOf
[ 1, 2, 3 ]
--> False
notMember : a -> List a -> Basics.Bool
Negation of member
.
notMember 1 [ 1, 2, 3 ]
--> False
notMember 4 [ 1, 2, 3 ]
--> True
find : (a -> Basics.Bool) -> List a -> Maybe a
Find the first element that satisfies a predicate and return Just that element. If none match, return Nothing.
find (\num -> num > 5) [ 2, 4, 6, 8 ]
--> Just 6
elemIndex : a -> List a -> Maybe Basics.Int
Return the index of the first occurrence of the element. Otherwise, return Nothing
. Indexing starts from 0.
elemIndex 1 [ 1, 2, 3 ]
--> Just 0
elemIndex 4 [ 1, 2, 3 ]
--> Nothing
elemIndex 1 [ 1, 2, 1 ]
--> Just 0
elemIndices : a -> List a -> List Basics.Int
Return all indices of occurrences of the element. If element is not found, return empty list. Indexing starts from 0.
elemIndices 1 [ 1, 2, 3 ]
--> [ 0 ]
elemIndices 4 [ 1, 2, 3 ]
--> []
elemIndices 1 [ 1, 2, 1 ]
--> [ 0, 2 ]
findIndex : (a -> Basics.Bool) -> List a -> Maybe Basics.Int
Take a predicate and a list, return the index of the first element that satisfies the predicate. Otherwise, return Nothing
. Indexing starts from 0.
isEven : Int -> Bool
isEven i =
modBy 2 i == 0
findIndex isEven [ 1, 2, 3 ]
--> Just 1
findIndex isEven [ 1, 3, 5 ]
--> Nothing
findIndex isEven [ 1, 2, 4 ]
--> Just 1
findIndices : (a -> Basics.Bool) -> List a -> List Basics.Int
Take a predicate and a list, return indices of all elements satisfying the predicate. Otherwise, return empty list. Indexing starts from 0.
isEven : Int -> Bool
isEven i =
modBy 2 i == 0
findIndices isEven [ 1, 2, 3 ]
--> [ 1 ]
findIndices isEven [ 1, 3, 5 ]
--> []
findIndices isEven [ 1, 2, 4 ]
--> [ 1, 2 ]
findMap : (a -> Maybe b) -> List a -> Maybe b
Apply a function that may succeed to values in the list and return the result of the first successful match. If none match, then return Nothing.
mapOverFive : Int -> Maybe Int
mapOverFive num =
if num > 5 then
Just (num * 2)
else
Nothing
findMap mapOverFive [2, 4, 6, 8]
--> Just 12
This is particularly useful in cases where you have a complex type in a list, and you need to pick out the the first one
type alias HouseModel =
{}
type Property
= Rental
| House HouseModel
| Commercial
toHouse : Property -> Maybe HouseModel
toHouse property =
case property of
House house ->
Just house
_ ->
Nothing
viewFirstHomeOfInterest : Viewer -> List Property -> Html msg
viewFirstHomeOfInterest viewer propertiesQuery =
propertiesQuery
|> findMap toHouse
|> Maybe.map homeView
|> Maybe.withDefault noHomeView
count : (a -> Basics.Bool) -> List a -> Basics.Int
Returns the number of elements in a list that satisfy a given predicate.
Equivalent to List.length (List.filter pred list)
but more efficient.
count
(modBy 2 >> (==) 1) [ 1, 2, 3, 4, 5, 6, 7 ]
--> 4
count
((==) "yeah")
[ "She", "loves", "you", "yeah", "yeah", "yeah" ]
--> 3
zip : List a -> List b -> List ( a, b )
Take two lists and returns a list of corresponding pairs
zip3 : List a -> List b -> List c -> List ( a, b, c )
Take three lists and returns a list of triples
lift2 : (a -> b -> c) -> List a -> List b -> List c
Map functions taking multiple arguments over multiple lists, regardless of list length. All possible combinations will be explored.
lift2 (+) [1,2,3][4,5]
--> [5,6,6,7,7,8]
lift3 : (a -> b -> c -> d) -> List a -> List b -> List c -> List d
Maps a function over three lists, exploring all possible combinations.
lift4 : (a -> b -> c -> d -> e) -> List a -> List b -> List c -> List d -> List e
Maps a function over four lists, exploring all possible combinations.
groupsOf : Basics.Int -> List a -> List (List a)
Split list into groups of length size
. If there are not enough elements
to completely fill the last group, it will not be included. This is equivalent
to calling groupsOfWithStep
with the same size
and step
.
groupsOf 3 (List.range 1 10)
--> [ [ 1, 2, 3 ], [ 4, 5, 6 ], [ 7, 8, 9 ] ]
groupsOfWithStep : Basics.Int -> Basics.Int -> List a -> List (List a)
Split list into groups of length size
at offsets step
apart. If there
are not enough elements to completely fill the last group, it will not be
included. (See greedyGroupsOfWithStep
if you would like the last group to be
included regardless.)
groupsOfWithStep 4 4 (List.range 1 10)
--> [ [ 1, 2, 3, 4 ], [ 5, 6, 7, 8 ] ]
groupsOfWithStep 3 1 (List.range 1 5)
--> [ [ 1, 2, 3 ], [ 2, 3, 4 ], [ 3, 4, 5 ] ]
groupsOfWithStep 3 6 (List.range 1 20)
--> [ [ 1, 2, 3 ], [ 7, 8, 9 ], [ 13, 14, 15 ] ]
If step == size
, every element (except for perhaps the last few due to the
non-greedy behavior) will appear in exactly one group. If step < size
, there
will be an overlap between groups. If step > size
, some elements will be
skipped and not appear in any groups.
groupsOfVarying : List Basics.Int -> List a -> List (List a)
groupsOfVarying ns
takes n
elements from a list for each n
in ns
, splitting the list into variably sized segments
groupsOfVarying [ 2, 3, 1 ] [ "a", "b", "c", "d", "e", "f" ]
--> [ [ "a", "b" ], [ "c", "d", "e" ], [ "f" ] ]
groupsOfVarying [ 2 ] [ "a", "b", "c", "d", "e", "f" ]
--> [ [ "a", "b" ] ]
groupsOfVarying [ 2, 3, 1, 5, 6 ] [ "a", "b", "c", "d", "e" ]
--> [ [ "a", "b" ], [ "c", "d", "e" ] ]
greedyGroupsOf : Basics.Int -> List a -> List (List a)
Greedily split list into groups of length size
. The last group of
elements will be included regardless of whether there are enough elements in
the list to completely fill it. This is equivalent to calling
greedyGroupsOfWithStep
with the same size
and step
.
greedyGroupsOf 3 (List.range 1 10)
--> [ [ 1, 2, 3 ], [ 4, 5, 6 ], [ 7, 8, 9 ], [ 10 ] ]
greedyGroupsOfWithStep : Basics.Int -> Basics.Int -> List a -> List (List a)
Greedily split list into groups of length size
at offsets step
apart.
The last group of elements will be included regardless of whether there are
enough elements in the list to completely fill it. (See groupsOfWithStep
for the non-greedy version of this function).
greedyGroupsOfWithStep 4 4 (List.range 1 10)
--> [ [ 1, 2, 3, 4 ], [ 5, 6, 7, 8 ], [ 9, 10 ] ]
greedyGroupsOfWithStep 3 2 (List.range 1 6)
--> [ [ 1, 2, 3 ], [ 3, 4, 5 ], [ 5, 6 ] ]
greedyGroupsOfWithStep 3 6 (List.range 1 20)
--> [ [ 1, 2, 3 ], [ 7, 8, 9 ], [ 13, 14, 15 ], [ 19, 20 ] ]
If step == size
, every element will appear in exactly one group. If
step < size
, there will be an overlap between groups. If step > size
, some
elements will be skipped and not appear in any groups.
joinOn : (a -> b -> c) -> (a -> comparable) -> (b -> comparable) -> List a -> List b -> List c
Performs an inner join, combining data items from both lists if they match by their respective key functions.
employees : List { name : String, departmentId : Int }
employees =
[ { name = "Rafferty", departmentId = 31 }
, { name = "Jones", departmentId = 33 }
, { name = "Heisenberg", departmentId = 33 }
, { name = "Robinson", departmentId = 34 }
, { name = "Smith", departmentId = 34 }
]
departments : List { name : String, departmentId : Int }
departments =
[ { departmentId = 31, name = "Sales" }
, { departmentId = 33, name = "Engineering" }
, { departmentId = 34, name = "Clerical" }
, { departmentId = 35, name = "Marketing" }
]
joinOn (\empl dep -> { employee = empl.name, department = dep.name}) .departmentId .departmentId employees departments
--> [ { department = "Clerical", employee = "Robinson" }
--> , { department = "Clerical", employee = "Smith" }
--> , { department = "Engineering", employee = "Jones" }
--> , { department = "Engineering", employee = "Heisenberg" }
--> , { department = "Sales", employee = "Rafferty" }
--> ]
This is akin to the SQL query:
SELECT employee.name, department.name
FROM employee
INNER JOIN department
ON employee.departmentId = department.departmentId