或者,你可以做
mapBut1 f(x:y:xs)= fx:mapBut1 f(y:xs)
mapBut1 f other =其他
它们是等价的定义,但后者使用1个较少的模式匹配。不过,我更喜欢前者,因为更直接明显的是正在处理哪些案件。
How do I best map over all elements of a list, except for the last list element?
Say we have a list let l = [1,2,3,4]
and want to get [2,3,4,4]
.
I do have a solution, but it doesn't feel like the "functional" way to do it (in ghci):
let l = [1,2,3,4]
let len = toIntegral $ length l -- to avoid a type mismatch Integer <-> Int
let l1 = zip l [1..]
let l2 = map (\(x,y) -> if y < len then (x + 1,y) else (x,y)) l1
let l3 = map (fst) l2
Not very nice...I do hope there is a better way! Since I'm a novice in functional programming, I don't know where to start looking for it though.
解决方案
Just re-write map
but make a special case when there's only one element:
mapBut1 :: (a -> a) -> [a] -> [a]
mapBut1 f [] = []
mapBut1 f [x] = [x]
mapBut1 f (x:xs) = f x : mapBut1 f xs
This will now work even for infinite lists, it's a lot faster than calculating the length, and makes it more readable. Note that this does restrict your function to be of type a -> a
instead of a -> b
.
Alternatively, you could do
mapBut1 f (x:y:xs) = f x : mapBut1 f (y:xs)
mapBut1 f other = other
They're equivalent definitions, but the latter uses 1 fewer pattern matches. I would prefer the former, though, since it's more immediately obvious what cases are being handled.
这篇关于映射到列表上,除了最后一个列表元素的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!