says that we want to filter out all the odd one in a list.
说我们要过滤掉列表中的所有奇数。
odd' (i,n) = odd i
unbox (i,n) = n
f :: [Int] -> [Int]
f lst = map unbox $ filter odd' $ zip [1..] lst
*Main> f [1,2,3,4]
[1,3]
it has the unpleasant boxing and unboxing.
它有令人不快的拳击和拆箱。
can we change the way we think this problem and eliminate boxing and unboxing?
我们可以改变我们认为这个问题的方式并消除拳击和拆箱吗?
@user3237465 list comprehension is indeed a good way of thinking this sort of problem. as well as function composition. well, I think we won't get rid of "wrapping the original list to [(index,value)] form and then unwrap it" without writing a special form like @Carsten König provided.
@ user3237465 list comprehension确实是思考这类问题的好方法。以及功能组成。好吧,我认为我们不会摆脱“将原始列表包装到[(索引,值)]表单然后打开它”,而不是像@CarstenKönig提供的那样写一个特殊的表单。
Or have a function that give out one value's index given the list and the value. like filter (odd . getindex) xs
或者有一个函数,给出列表和值给出一个值的索引。喜欢过滤器(odd.getindex)xs
and maybe that's why clojure made it's pattern matching strong enough to get value in complex structure.
也许这就是为什么clojure使它的模式匹配足以在复杂结构中获得价值的原因。
2 个解决方案
#1
you can always rewrite the function if you want - this comes to mind:
你可以随时重写这个功能 - 想到这个:
odds :: [a] -> [a]
odds (x:_:xs) = x : odds xs
odds [x] = [x]
odds _ = []
aside from this both you don't need odd'
and unbox
:
除此之外你不需要奇怪的'和unbox:
-
odd'
is justodd . fst
-
unbox
is justsnd
奇怪'只是奇怪的。 FST
unbox就是这样
#2
You can write this as
你可以这样写
f xs = [x | (i, x) <- zip [0..] xs, even i]
or
f = snd . foldr (\x ~(o, e) -> (e, x : o)) ([], [])
or
import Data.Either
f = lefts . zipWith ($) (cycle [Left, Right])
#1
you can always rewrite the function if you want - this comes to mind:
你可以随时重写这个功能 - 想到这个:
odds :: [a] -> [a]
odds (x:_:xs) = x : odds xs
odds [x] = [x]
odds _ = []
aside from this both you don't need odd'
and unbox
:
除此之外你不需要奇怪的'和unbox:
-
odd'
is justodd . fst
-
unbox
is justsnd
奇怪'只是奇怪的。 FST
unbox就是这样
#2
You can write this as
你可以这样写
f xs = [x | (i, x) <- zip [0..] xs, even i]
or
f = snd . foldr (\x ~(o, e) -> (e, x : o)) ([], [])
or
import Data.Either
f = lefts . zipWith ($) (cycle [Left, Right])