2009-09-30 15 views
23

Ho una funzione in Haskell che trova il valore massimo di un elevamento a potenza da una lista:Trovare l'indice dell'elemento in una lista in Haskell?

prob99 = maximum $ map (\xs -> (head xs)^(head (tail xs))) numbers 

Che cosa ho bisogno di trovare è la posizione di questo valore massimo nella lista risultante. Come andrei su questo?

Edit: ho trovato una soluzione che va in questo modo:

n = [[519432,525806],[632382,518061].... 
prob99b [a,b] = b* (log a) 
answer = snd $ maximum (zip (map prob99b n) [1..]) 

risposta

29

Come trovare l'indice dell'elemento massimo? Che ne dici di provare tutti gli indici e verificare se sono il massimo?

ghci> let maxIndex xs = head $ filter ((== maximum xs) . (xs !!)) [0..] 

Ma questo suona come qualcosa per cui esiste già una funzione. Il mio codice sarà più leggibile, manutenibile e probabilmente anche più efficiente, se avessi usato la funzione esistente.

Quindi dovrei solo chiedere SO come farlo, e in 15 minuti riceverò una risposta e alcuni commenti snarky. O - Potrei chiedere Hoogle e ottenere una risposta utile diementicato (come suggerito Will)

$ hoogle "Ord a => [a] -> Int" | head 

<Nothing relevant> 

$ # hmm, so no function to give me the index of maximum outright, 
$ # but how about finding a specific element, and I give it the maximum? 
$ hoogle "a -> [a] -> Int" | head 
Data.List elemIndex :: Eq a => a -> [a] -> Maybe Int 
Data.List elemIndices :: Eq a => a -> [a] -> [Int] 
+30

Beh, sembra che tutti tranne me fossero appena nati fantastici ora non erano loro Ma in realtà, non sapevo nemmeno che esistesse Hoogle e sto ancora imparando Haskell, lo saprò meglio la prossima volta .. –

+5

@Jonno_FTW: Mi scuso per essere snarky/cinico Non tutti sono nati fantastici, e alcune persone sono senza essere nati in quel modo. Probabilmente puoi diventare anche fantastico. Una buona regola nella programmazione Pythonesque è: se scopro che sto codificando la stessa cosa cosa 3 volte, forse dovrei fare una funzione per esso.In programmazione Haskellesque la costante è e invece di 3. La stessa regola si applica anche nella meta-programmazione.Se scopri che hai bisogno di trovarci Una buona funzione in abbondanza, meglio provare a scoprire se esiste un modo migliore per eseguire questo processo di ricerca delle funzioni e quindi scoprire Hoogle. mtfbwu – yairchu

+5

@Jonno_FTW Non iniziare a utilizzare Hoogle se non sei pronto a diventare dipendente da esso. Come programmatore Haskell più esperto, mi rivolgo a Hoogle non appena ho identificato i tipi coinvolti in ciò che sto cercando di fare.Questo è un problema quando sto programmando ad es. Python, quando mi sento frustrato perché non c'è Poogle. :( – kqr

31
import Data.List 
elemIndex 'b' "abc" === Just 1 

Davvero un buon strumento per la ricerca di funzioni di Haskell è Hoogle. Permette di cercare per tipo di firma tra le altre cose.

Se si desidera eseguire tutto in un unico passaggio, si consiglia Data.List.mapAccumL, passando l'indice del numero più grande trovato finora lungo l'accumulatore.

+0

Puoi dire come convertire l'output di 'elemIndex' in' Int' (non 'Maybe Int'? – Shashwat

+0

@Sashwat: http://stackoverflow.com/questions/3643172/using-maybe-type-in- haskell –

6

Questo probabilmente non merita di essere in una risposta di suo, ma non posso commentare ancora. In ogni caso, ecco come avrei scritto questo:

import Data.List 
import Data.Ord 

maxIndex :: Ord a => [a] -> Int 
maxIndex = fst . maximumBy (comparing snd) . zip [0..] 
1

Se si sta facendo il calcolo numerico in Haskell, si potrebbe voler guardare in librerie che rendono più facile e più efficiente. Per esempio hmatrix ha un metodo per maxIndex efficienti Vector s, la documentazione di cui è qui: https://hackage.haskell.org/package/hmatrix-0.17.0.1/docs/Numeric-LinearAlgebra-Data.html#g:14

> maxIndex $ vector [1, 3, 2] 
1 

I nomi esatti dei metodi erano diversi in cui la questione è stata originariamente chiesto, ma la biblioteca era intorno allora troppo.

Problemi correlati