2011-12-30 9 views
12

どのようにしてリストを同じ長さのリスト(最後のサブリストを除く)にグループ化できますか?haskellでリストを細分化する

など。

sublist 3 [1,2,3,4,5,6,7,8] -> [[1,2,3],[4,5,6],[7,8]] 
sublist 2 [4,1,6,1,7,3,5,3] -> [[4,1],[6,1],[7,3],[5,3]] 

答えて

9

、あなたがsplitAtを使用して、これをやってのけることができます。

splitEvery _ [] = [] 
splitEvery n list = first : (splitEvery n rest) 
    where 
    (first,rest) = splitAt n list 
+1

あるいは 'splitEvery N = takeWhile(NOT NULL):「splitEvery」 非推奨の使用において 。 unfoldr(Just。splitAt n) ' – newacct

21

試してください:あなたは前奏曲に固執する場合

import Data.List.Split 
> splitEvery 2 [4,1,6,1,7,3,5,3] 
[[4,1],[6,1],[7,3],[5,3]] 
+7

[split](http://hackage.haskell.org/package/split)パッケージを先にインストールする必要があります。私のような初心者のための – ehird

+3

- それは 'cabal install split'を実行することを意味します –

+4

実際には、' splitEvery'はまだ推奨されていますか? ':1:1警告: "使用chunksOf。"' –

5

私が好きなもう一つの解決策は以下のとおりです。

splitEvery :: Int -> [a] -> [[a]] 
splitEvery n = takeWhile (not.null) . map (take n) . iterate (drop n) 
2

は、さらに別の解決策:

split :: Int -> [a] -> [[a]] 
split n = unfoldr (\s -> if null s then Nothing else Just $ splitAt n s) 
0

これがある人々のためのポストのようですので、私はこれが古いですけど、かなり新しい、ハスケル、私は私の解決策を投稿するように感じた。私は、プレリュードを使用することで、この問題を解決しようとした:

sublist :: Int -> [a] -> [[a]] 
sublist n ls 
    | n <= 0 || null ls = [] 
    | otherwise = take n ls:sublist n (drop n ls) 

をテスト

sublist 3 [1,2,3,4,5,6] -- λ> [[1,2,3], [4,5,6]] 
sublist 5 [1,2,3]  -- λ> [[1,2,3]] 
sublist (-1) [1,2,3] -- λ> [] 
sublist 20 []   -- λ> [] 
6

Data.List.SplitモジュールはこのためchunksOf機能を持っています

Prelude> import Data.List.Split 

Prelude Data.List.Split> chunksOf 3 [1,2,3,4,5,6,7,8,9,10] 
[[1,2,3],[4,5,6],[7,8,9],[10]] 
Prelude Data.List.Split> chunksOf 3 [] 
[] 

によってインストールされるように見えました私のマシンのデフォルトですが、カバールで取得する必要があります。

関連する問題