Reputation: 3164
Say I have a list l
of type [(Int, Integer)]
such that the first element in every tuple is a (unique) index i
in the range 0
to n
and the second element in every tuple is an associated value v
.
I want to "expand" this list into a list of l'
type [Integer]
with length 10
such that l !! i == v
for all (i,v)
in l
and l !! j == 0
if (j,_)
is not in l
.
I.e.: [(1,10),(6,7)] => [0,10,0,0,0,0,7,0,0,0]
I'm not sure how to do this, I have tried:
map (\i -> lookup i l) [0..n]
That works except that the result is a list of Maybe's. An obvious solution is:
integerOrZero :: Maybe Integer -> Integer
integerOrZero Nothing = 0
integerOrZero (Just n) = n
And then:
map integerOrZero $ map (\i -> lookup i l) [0..n]
But I was wondering if there is a simpler way (maybe a one-liner) to write this "lookup with default". I guess mayMaybe
doesn't work here.
Context: I'm trying to produce a histogram of values between 0
and n
given a list of them, so overall I have thus far:
import Data.List (group, sort)
hist l = map integerOrZero $ map (\i -> lookup i l') [0..n]
where l' = map (\x -> (head x, length x)) $ group $ sort l
I would like to write this as succinctly as possible using only functions from the base
package.
Upvotes: 0
Views: 557
Reputation: 1333
There is Data.Maybe.fromMaybe
, it is often forgotten.
If you use Data.Map.Strict
, there is a better choice. findWithDefault must be what you want.
Upvotes: 5