2014-12-05 51 views
0

走向如何走线槽在Haskell列表时,列表中的样子:通过列表在Haskell

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

,我要采取的第一个3个元素:

[1,2,3] 

,然后去下3个元素:

[2,3,4] 

等等...

+0

fpcomplete的hoogle搜索比haskell.org的更为广泛:搜索功能它采用一个列表和一个整数,并给你一堆列表[a] - > Int - > [[a]] [有一些方便的结果](https://www.fpcomplete.com/hoogle?q=%5Ba %5D + - %3E + Int + - %3E +%5B%5Ba%5D%5D&env = ghc-7.8-stable-14.09) – AndrewC 2014-12-05 09:47:35

+0

带他们去做什么?在什么情况下继续?这个问题相当模糊。 – dfeuer 2014-12-05 11:29:52

+0

列表末尾应该发生什么? – dfeuer 2014-12-05 11:34:51

回答

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

定义你的函数类似这样slideThree (x:y:z:xs) =和你的递归调用,调用它slideThree (y:z:xs)

确保如果列表中包含至少三个元素,添加适当的检查。

+1

你的意思是'slideThree(y:z:xs)',也许? – chi 2014-12-05 10:54:41

3

要创建元素的滑动列表中,我们可以使用tails从Data.List模块

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] 
+0

我喜欢'tails'用法,但'filter'和'length'打扰了我。乍一看,'takeWhile'会更好。那么,如果要手动计算长度呢?然而,这可能会迫使这个名单并可能破坏融合。 – Yuuri 2014-12-05 11:53:55

1

其他的答案是好的 - 我只想补充一点,有一个简洁的列表理解:

[[x,y,z] | x:y:z:_ <- tails xs] 

显然,这是行不通的那么好,如果你想1000元的子列表,而不是3

此外,你应该忽略这一点,但我无法抗拒的乐趣自由点回答投掷:

zipWith (const (take 3)) <$> drop 2 <*> tails