如果列表如下所示,我如何通过Haskell中的列表:
[1,2,3,4,5,6,7,8,9,10,11,12]
我想采取前3个要素:
[1,2,3]
然后转到接下来的3个元素:
[2,3,4]
依旧......
答案 0 :(得分:3)
定义您的函数,就像这个slideThree (x:y:z:xs) =
一样,在您的递归调用中,将其称为slideThree (y:z:xs)
如果列表包含至少三个元素,请务必添加正确的检查。
答案 1 :(得分:3)
要创建元素的滑动列表,我们可以使用Data.List
中的tails
slide :: Int -> [a] -> [[a]]
slide n xs =
(filter (\xs -> length xs == n) . -- filter out all of length n
map (take n) . -- take only the first n elements of every tail
tails) xs -- find all tails
使用它:
λ> slide 3 [1..12]
[[1,2,3],[2,3,4],[3,4,5],[4,5,6],[5,6,7],[6,7,8],[7,8,9],[8,9,10],[9,10,11],[10,11,12]]
λ> map (\(x:y:z:[]) -> x + y + z) it
[6,9,12,15,18,21,24,27,30,33]
答案 2 :(得分:3)
您可以使用zipWith3
:
zipWith3 (\a b c -> [a,b,c]) xs (drop 1 xs) (drop 2 xs)
但是为什么在人们可以概括的时候停在那里?
subLists :: Int -> [a] -> [[a]]
subLists n xs =
let ts = take n xs
in if length ts == n
then ts : subLists n (tail xs)
else []
此解决方案可以通过takeN :: Int -> [a] -> Maybe [a]
进行改进,因此我们不需要检查ts
的长度,但这样做是为了练习;)。
答案 3 :(得分:1)
其他答案都很好 - 我只想补充一点,这是一个简洁的列表理解:
[[x,y,z] | x:y:z:_ <- tails xs]
显然,如果您想要1000个元素的子列表而不是3个,那么这将无法正常工作。
另外,你应该忽略这一点,但我无法抗拒投掷一个有趣的无点答案:
zipWith (const (take 3)) <$> drop 2 <*> tails