2014-12-05 49 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