2011-12-16 8 views
16

Probabilmente è facile, ma ho esaminato i documenti e cercato su Google gli esempi e non sono ancora sicuro della risposta.Ottieni una sottolista in Haskell

Se ho una lista come questa:

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

e voglio estrarre una fetta, dire dall'indice 4 all'indice 8 vale a dire che voglio:

[5,6,7,8,9] 

Qual è il modo idiomatico fare questo in Haskell?

+0

possibile duplicato del [fa Haskell avere Lista Slices (cioè Python)?] (Http://stackoverflow.com/questions/4597820/does-haskell-have-list-slices-ie-python) –

risposta

30

Prima di tutto, non è un array, è un elenco. Non sono (semplicemente) pedante, poiché gli array sono molto più problematici in Haskell che negli elenchi.

Detto, un modo comune è quello di utilizzare take e drop insieme:

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] 

Quest'ultimo è un po 'più efficiente.

+0

fantastico grazie - Ho anche corretto per dire lista piuttosto che array :) – PeterM

+0

Problematico? Non dovrebbero essere usati per tutto, e i moduli array standard non sono molto piacevoli, ma [vector] (http://hackage.haskell.org/package/vector) è molto utile quando è applicabile. Anche se sono d'accordo sul fatto che la competenza con le liste dovrebbe essere raggiunta prima di provare a usarli ... – ehird

+1

@ehird: hai appena elencato i motivi principali per cui li ho chiamati problematici. Quello che non li ho chiamati era "non utile" e "dannoso" :-) – ibid

3

Potresti essere interessato a 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] 

noti che slice in Data.Vector prende in ingresso il inizio dell'indice e lunghezza della fetta.

0

Hmmm, non molto pratico, ma forse può essere migliorato?

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

Che ne dici di 'map snd. filtro (liftA2 (&&) (> = 4) (<9). fst). zip [0 ..] '(nota' (<9) 'per abbinare il comportamento della domanda)? – ehird

+0

L'approccio decor-process-undecorate sembra molto lavoro extra per questo problema. –

+0

Forse dovrebbe esserci qualcosa come 'indexedFilter f = map snd. filtro (f.fst). zip [0 ..] 'o una generalizzazione nelle librerie? – Landei

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

[5,6,7,8,9] 
Problemi correlati