2012-12-23 132 views
17

對於Scala List [Int]我可以調用max方法來查找最大元素值。如何在Scala中找到列表中最大值的索引?

如何找到最大元素的索引?

這就是我現在所做的:

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

聽起來像一個奇怪的使用情況。也許使用需要一個有序的數據結構? – andyczerwonka

+0

是的,你有一個關於奇怪用例的觀點,你可以說這是「代碼異味」,因爲在首先生成列表時可以找到最大值。在這個小空間裏沒有足夠的空間來解釋爲什麼它看起來不對,也許我會在稍後更新答案。 – Phil

回答

34

的一種方式做到這一點是要壓縮其索引列表中,找到所產生的對與最大的第一個元素,並返回的第二元素對:

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

這不是解決問題的最有效的方法,但它的慣用和清晰。

+0

該死的,正是我剛纔說的...我添加了一個案例 'x.zipWithIndex.maxBy {case(i,v)=> v} ._ 2' – 2012-12-23 20:18:10

1

更容易閱讀是:

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

皮條客我的圖書館! :)

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) 

此處詳細瞭解此模式的細節:http://www.artima.com/weblogs/viewpost.jsp?thread=179766

+0

雖然很容易寫,不是嗎?兩次瀏覽列表? –

+0

是的你是對的。我有一種通過列表獲得最大值的方法,但我認爲可讀性對此有很大的影響。此外,它涉及使用myList(索引)來獲取特定項目,我不知道這是多高效 –

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 

的情況下有多個最大值,它返回的第一個索引。優點:你可以在多種類型中使用它,它只經歷一次列表,你可以提供一個默認索引,而不是空列表的異常。

缺點:也許你更喜歡例外情況:)不是一句話。

+0

嗨,我在哪裏可以讀到有關<%和<:操作符的含義,在Google上搜索相當困難或任何地方)的運營商是不是話語。另外,我想也許你可以在你的答案中使用tailrec([例子](https://gist.github.com/trylks/6164315))。謝謝。 – Trylks

+0

[Found!](http://ofps.oreilly.com/titles/9780596155957/ScalasTypeSystem.html)對不起。 – Trylks

4

由於Seq是Scala的功能,下面的代碼工作:

list.indices.maxBy(list) 
相關問題