2011-12-30 21 views
12

Jak pogrupować listę na mniejsze listy o równej długości (z wyjątkiem ostatniej listy) w haskell?Dzielenie listy w 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]] 

Odpowiedz

9

Jeśli chcesz trzymać się preludium, możesz to zdjąć za pomocą splitAt.

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

nawet 'splitEvery n = takeWhile (NULL.). unfoldr (Po prostu splitAt n) ' – newacct

21

Spróbuj:

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

Najpierw musisz zainstalować pakiet [split] (http://hackage.haskell.org/package/split). – ehird

+3

dla początkujących, takich jak ja - to znaczy, że uruchomiono 'cabal install split' –

+4

Czy w dalszym ciągu zalecane jest' splitEvery'? ': 1: 1: Uwaga: W zastosowaniu Przestarzały„splitEvery”: " Zastosowanie chunksOf"' –

5

Innym rozwiązaniem, które lubię jest:

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

Jeszcze innym rozwiązaniem:

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

wiem, że to jest stary, ale ponieważ to wydaje się być stanowisko dla ludzi, którzy są całkiem nowe dla Haskella, miałem ochotę opublikować moje rozwiązanie. Starałem się rozwiązać ten problem za pomocą Prelude, tylko:

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

Testowanie

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

Moduł Data.List.Split ma chunksOf funkcję dla tego:

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

Wydawało być instalowane domyślnie na moim komputerze, ale może być konieczne pobranie go z kabałą.