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
W przypadku istnieje wiele maksima, zwraca pierwszy za indeks.
Plusy: Możesz używać tego z wieloma typami, lista jest wyświetlana tylko raz, możesz podać indeks domyślny zamiast wyjątku dla pustych list.
Minusy: Może wolisz wyjątki :) Nie jeden liniowiec.
brzmi jak dziwny przypadek użycia. może trzeba użyć posortowanej struktury danych? – andyczerwonka
Tak, masz rację co do dziwnego przypadku użycia, możesz powiedzieć, że jest to "zapach kodu", ponieważ maksimum mogło zostać znalezione podczas generowania listy w pierwszej kolejności. Nie ma wystarczająco dużo miejsca, aby dowiedzieć się, dlaczego w tej niewielkiej przestrzeni wydaje się źle, może zaktualizuję odpowiedź później. – Phil