2012-12-23 7 views
17

Per una lista Scala [Int] Posso chiamare il metodo max per trovare il valore massimo dell'elemento.Come posso trovare l'indice del valore massimo in una lista in Scala?

Come posso trovare l'indice dell'elemento massima?

Questo è quello che sto facendo ora:

val max = list.max 
val index = list.indexOf(max) 
+0

suona come un caso d'uso strano. forse usare bisogno di una struttura di dati ordinati? – andyczerwonka

+0

Sì, hai un punto sullo strano caso d'uso, potresti dire che è "odore di codice" dato che il massimo potrebbe essere stato trovato durante la generazione dell'elenco in primo luogo. Non c'è abbastanza spazio per entrare nel motivo per cui sembra sbagliato qui in questo piccolo spazio, forse aggiornerò la risposta più tardi. – Phil

risposta

34

Un modo per farlo è quello di comprimere la lista con i suoi indici, trovare la coppia risultante con il più grande primo elemento, e restituire il secondo elemento di tale coppia:

scala> List(0, 43, 1, 34, 10).zipWithIndex.maxBy(_._1)._2 
res0: Int = 1 

Questo non è il modo più efficace per risolvere il problema, ma è idiomatica e chiaro.

+0

dannazione, esattamente quello che stavo per dire ... ho aggiunto un caso 'x.zipWithIndex.maxBy {caso (i, v) => v} ._ 2' –

1

ancora più facile da leggere sarebbe:

val g = List(0, 43, 1, 34, 10) 
    val g_index=g.indexOf(g.max) 
0

Pimp my library! :)

class AwesomeList(list: List[Int]) { 
    def getMaxIndex: Int = { 
    val max = list.max 
    list.indexOf(max) 
    } 
} 

implicit def makeAwesomeList(xs: List[Int]) = new AwesomeList(xs) 
               //> makeAwesomeList: (xs: List[Int])scalaconsole.scratchie1.AwesomeList 

//Now we can do this: 
List(4,2,7,1,5,6) getMaxIndex    //> res0: Int = 2 

//And also this: 
val myList = List(4,2,7,1,5,6)   //> myList : List[Int] = List(4, 2, 7, 1, 5, 6) 
myList getMaxIndex      //> res1: Int = 2 

//Regular list methods also work 
myList filter (_%2==0)     //> res2: List[Int] = List(4, 2, 6) 

Maggiori informazioni su questo modello qui: http://www.artima.com/weblogs/viewpost.jsp?thread=179766

+0

Mentre è facile da scrivere, non è vero? passare attraverso la lista due volte? –

+0

Sì hai ragione. Ho un modo di ottenere il massimo in un'unica iterazione attraverso la lista, ma penso che la leggibilità abbia un grande successo. Inoltre, implica l'uso di myList (index) per recuperare l'oggetto in particolare e non sono sicuro di quanto sia efficace –

1
def maxIndex[ T <% Ordered[T] ] (list : List[T]) : Option[Int] = list match { 
    case Nil => None 
    case head::tail => Some(
     tail.foldLeft((0, head, 0)){ 
      case ((indexOfMaximum, maximum, index), elem) => 
       if(elem > maximum) (index, elem, index + 1) 
       else (indexOfMaximum, maximum, index + 1) 
     }._1 
    ) 
    } //> maxIndex: [T](list: List[T])(implicit evidence$2: T => Ordered[T])Option[Int] 


    maxIndex(Nil)       //> res0: Option[Int] = None 
    maxIndex(List(1,2,3,4,3))    //> res1: Option[Int] = Some(3) 
    maxIndex(List("a","x","c","d","e"))  //> res2: Option[Int] = Some(1) 

    maxIndex(Nil).getOrElse(-1)    //> res3: Int = -1 
    maxIndex(List(1,2,3,4,3)).getOrElse(-1) //> res4: Int = 3 
    maxIndex(List(1,2,2,1)).getOrElse(-1) //> res5: Int = 1 

Nel caso in cui ci sono più massimi, restituisce l'indice prima di uno.

Pro: È possibile utilizzare questo con più tipi, passa attraverso la lista solo una volta, è possibile fornire un indice di default invece di ottenere eccezione per gli elenchi vuoti.

Contro: forse si preferisce eccezioni :) Non una battuta.

+0

Ciao, dove posso leggere il significato di <% e <: operatori, è piuttosto difficile cercare su Google (o ovunque) per gli operatori che non sono parole. Inoltre, penso che potresti usare tailrec nella tua risposta ([esempio] (https://gist.github.com/trylks/6164315)). Grazie. – Trylks

+0

[Found!] (Http://ofps.oreilly.com/titles/9780596155957/ScalasTypeSystem.html) Ci scusiamo per la richiesta. – Trylks

4

Dal Seq è una funzione a Scala, il seguente codice funziona:

list.indices.maxBy(list) 
Problemi correlati