Скажем, у меня есть список l
типа [(Int, Integer)]
, в котором первый элемент в каждом кортеже является (уникальным) индексом i
в диапазоне от 0
до n
, а второй элемент в каждом кортеже является ассоциированным значением v
.
Я хочу «расширить» этот список в список типа l'
[Integer]
с длиной 10
, такой что l !! i == v
для всех (i,v)
в l
и l !! j == 0
, если (j,_)
не находится в l
.
То есть: [(1,10),(6,7)] => [0,10,0,0,0,0,7,0,0,0]
Я не уверен, как это сделать, я пробовал:
map (\i -> lookup i l) [0..n]
Это работает, за исключением того, что результатом является список Maybe. Очевидное решение:
integerOrZero :: Maybe Integer -> Integer
integerOrZero Nothing = 0
integerOrZero (Just n) = n
А потом:
map integerOrZero $ map (\i -> lookup i l) [0..n]
Но мне было интересно, есть ли более простой способ (возможно, однострочный) написать этот «поиск по умолчанию». Я думаю, mayMaybe
здесь не работает.
Контекст: я пытаюсь создать гистограмму значений между 0
и n
с учетом их списка, поэтому в целом я до сих пор:
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
Я хотел бы написать это максимально лаконично, используя только функции из пакета base
.
Есть Data.Maybe.fromMaybe
, про него часто забывают.
Данные.Может быть
Если вы используете Data.Map.Strict
, есть лучший выбор. findWithDefault должно быть то, что вы хотите.