浏览Haskell中的列表

时间:2014-12-05 09:23:31

标签: haskell

如果列表如下所示,我如何通过Haskell中的列表:

[1,2,3,4,5,6,7,8,9,10,11,12]

我想采取前3个要素:

[1,2,3]

然后转到接下来的3个元素:

[2,3,4]

依旧......

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