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.
suona come un caso d'uso strano. forse usare bisogno di una struttura di dati ordinati? – andyczerwonka
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