2011-12-16 31 views
16

Probablemente uno fácil, pero he revisado los documentos y busqué ejemplos en Google y todavía no estoy seguro de la respuesta.Obtener una sublista en Haskell

Si tengo una lista como esta:

[1,2,3,4,5,6,7,8,9,0] 

y quiero extraer una rebanada, digamos de índice de 4 a 8 Índice de decir que quiero:

[5,6,7,8,9] 

Cuál es la forma idiomática hacer esto en Haskell?

+0

posible duplicado de [¿El Haskell tienen Lista rebanadas (es decir, Python)?] (Http://stackoverflow.com/questions/4597820/does-haskell-have-list-slices-ie-python) –

Respuesta

30

En primer lugar, eso no es una matriz, es una lista. No estoy siendo (meramente) pedante, ya que las matrices son mucho más problemáticas en Haskell que las listas.

Dicho esto, una forma común es el uso de take y drop juntos:

Prelude> drop 4 . take 9 $ [1,2,3,4,5,6,7,8,9,0] 
[5,6,7,8,9] 
Prelude> take (9-4) . drop 4 $ [1,2,3,4,5,6,7,8,9,0] 
[5,6,7,8,9] 

Este último es un poco más eficiente.

+0

gracias increíbles - También lo he corregido para decir lista en lugar de matriz :) – PeterM

+0

Problematic? No deberían usarse para todo, y los módulos de matriz estándar no son muy agradables, pero [vector] (http://hackage.haskell.org/package/vector) es muy útil cuando es aplicable. Aunque estoy de acuerdo en que se debe alcanzar el dominio de las listas antes de intentar usarlas ... – ehird

+1

@ehird: Acabas de enumerar las principales razones por las que las llamé problemáticas. Lo que no los llamé fue "no útil" y "dañino" :-) – ibid

3

Puede que le interese el Data.Vector (slice).

ghci> import Data.Vector 
ghci> let v = fromList [1..10] 
ghci> v 
fromList [1,2,3,4,5,6,7,8,9,10] 
ghci> slice 4 5 v 
fromList [5,6,7,8,9] 

Tenga en cuenta que en sliceData.Vector toma como entradas la comenzando índice y la longitud de la rebanada .

0

Hmmm, no es muy práctico, pero tal vez se puede mejorar?

(\(x,y) -> if 4 <= y && y <= 9 then [x] else []) =<< zip [1,2,3,4,5,6,7,8,9] [0..] 
+0

¿Qué tal 'map snd. filtro (liftA2 (&&) (> = 4) (<9). fst). zip [0 ..] '(nota' (<9) 'para que coincida con el comportamiento de la pregunta)? – ehird

+0

El enfoque decorate-process-undecorate parece mucho trabajo adicional para este problema. –

+0

Tal vez debería haber algo como 'indexedFilter f = map snd. filtro (f.fst). zip [0 ..] 'o una generalización en las libs? – Landei

4
> drop 4 (take 9 [1,2,3,4,5,6,7,8,9,0]) 

[5,6,7,8,9] 
Cuestiones relacionadas