2011-12-30 19 views
12

¿Cómo puedo agrupar una lista en listas más pequeñas de igual longitud (excepto la última sublista) en haskell?Subdividiendo una lista en 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]] 

Respuesta

9

Si usted quiere meter a preludio, se puede sacar esto adelante usando splitAt.

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

o incluso 'splitEvery n = takeWhile (no nulo.). despliegue (Just. splitAt n) ' – newacct

21

Probar:

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

Primero tendrá que instalar el paquete [split] (http://hackage.haskell.org/package/split). – ehird

+3

para principiantes como yo, eso significa ejecutar 'cabal install split' –

+4

En realidad, ¿todavía se recomienda' splitEvery'? ': 1: 1: Advertencia: En el uso de Deprecated‘splitEvery’: " Uso chunksOf"' –

5

Otra solución que me gusta es:

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

Sin embargo, otra solución:

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

Sé que esto es viejo, pero ya que este parece ser un mensaje para personas que están bastante nuevo para Haskell, tenía ganas de publicar mi solución también. Me tratado de resolver este problema mediante el uso de preludio, solamente:

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

Prueba

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

El módulo Data.List.Split tiene una función chunksOf para esto:

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

Parecía ser instalado por predeterminado en mi máquina, pero es posible que deba obtenerlo con cabal.

Cuestiones relacionadas