2013-04-24 12 views
13

Come posso ottenere l'indice dell'elemento in cui mi trovo in haskell quando utilizzo la mappa?Indice dell'elemento nell'elenco in Haskell

Ad esempio, ho questo elenco l = "a+bc?|(de)*fg|h" e desidero conoscere l'indice esatto dell'elemento in cui mi trovo quando utilizzo la funzione map or scanl.

risposta

26

Prima di tutto, se è necessario un indice durante l'elaborazione di un elenco, è un certo segno che si sta implementando un algoritmo non ottimale, perché l'elenco non è una struttura basata su indici come array. Se è necessario gestire gli indici, è meglio prendere in considerazione l'utilizzo di vector.

Per quanto riguarda la tua domanda attuale, è possibile associare gli elementi della vostra lista con incremento interi con il seguente codice e quindi mappare sul risultato:

Prelude> zip [0..] "a+bc?|(de)*fg|h" :: [(Int, Char)] 
[(0,'a'),(1,'+'),(2,'b'),(3,'c'),(4,'?'),(5,'|'),(6,'('),(7,'d'),(8,'e'),(9,')'),(10,'*'),(11,'f'),(12,'g'),(13,'|'),(14,'h')] 
+10

Avere gli indici a disposizione è un requisito piuttosto comune durante l'elaborazione degli elenchi (ad esempio per la segnalazione degli errori). –

+8

Ci sono molti usi per un indice quando si elabora un elenco che non ha nulla a che fare con l'utilizzo di un algoritmo subottimale. Quindi è un segno molto incerto. –

27

La modifica la risposta di Nikita Volkov, è possibile utilizzare una funzione come :

-- variant of map that passes each element's index as a second argument to f 
mapInd :: (a -> Int -> b) -> [a] -> [b] 
mapInd f l = zipWith f l [0..] 
+3

Oppure 'mapInd f l = zipWith f l [0 ..]'. – dave4420

+0

@ dave4420: buon punto, grazie. –

+2

È passato molto tempo, ma per brevità funziona anche: 'mapInd f = zipWith f [0 ..]' – Kittsil