映射到列表上,除了最后一个列表元素 [英] Map over list, except for last list element
问题描述
假设我们有一个列表让我们把列表中的所有元素映射到列表的所有元素上= [1,2,3,4]
并且想获得 [2,3,4,4]
。
我确实有一个解决方案,但它并不像实用方法(ghci):
let l = [1,2,3,4]
let len = toIntegral $ length l - 避免类型不匹配整数< - > ;如果y< len then(x + 1,y)else(x(x,y))>如果y< ,y))l1
let l3 = map(fst)l2
不太好。 ..我希望有更好的方法!因为我是函数式编程的新手,所以我不知道从哪里开始寻找它。
-write map
,但在只有一个元素时做一个特例:
mapBut1 ::(a - > a) - > [a] - > [a]
mapBut1 f [] = []
mapBut1 f [x] = [x]
mapBut1 f(x:xs)= fx:mapBut1 f xs
即使对于无限列表,它现在也可以工作,它比计算长度快很多,并且使其更具可读性。请注意,这会限制你的函数的类型为 a - > a
而不是 a - > b
。
或者,你可以做
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.
这篇关于映射到列表上,除了最后一个列表元素的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!