2011-12-30 2 views
12

Как я могу сгруппировать список в меньшие списки равной длины (кроме последнего подсписок) в haskell?Разделение списка в haskell

E.g.

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 п = TakeWhile (не нуль.). unoldr (Just. splitAt n) ' – newacct

21

Try:

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: Предупреждение: При использовании«»splitEvery DEPRECATED: " Использование 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

Я знаю, что это старый, но так как это, кажется, пост для людей, которые довольно новый для Haskell, мне тоже хотелось опубликовать мое решение. Я попытался решить эту проблему с помощью Prelude, только:

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 [] 
[] 

Казалось, установлен по умолчанию на моей машине, но вам может понадобиться получить его с помощью cabal.

Смежные вопросы