17

我有以下元组列表:

val arr = List(('a',10),('b',2),('c',3))

如何找到具有最大键或最大值的元组?

正确的答案应该是(c, 3)按字典顺序的最大键或('a', 10)最大值。

4

3 回答 3

43

十分简单:

scala> val list = List(('a',10),('b',2),('c',3))
list: List[(Char, Int)] = List((a,10), (b,2), (c,3))

scala> val maxByKey = list.maxBy(_._1)
maxByKey: (Char, Int) = (c,3)

scala> val maxByVal = list.maxBy(_._2)
maxByVal: (Char, Int) = (a,10)

因此,基本上您可以提供任何用于查找最大值的List[T]函数T => BB可以是任何有序类型,例如Int或示例)。String

于 2013-04-02T16:32:32.250 回答
4

从 开始Scala 2.13,一个稍微安全的解决方案(处理空列表)将包括使用maxByOption/如果序列为空则minByOption返回:None

List(('a', 10),('b', 2),('c', 3)).maxByOption(_._1)
// Option[(Char, Int)] = Some((c,3))
List[(Char, Int)]().maxByOption(_._1)
// Option[(Char, Int)] = None

这样,您还可以决定在列表为空时回退到默认值:

List[(Char, Int)]().maxByOption(_._1).getOrElse(('a', 1))
// (Char, Int) = (a,1)
于 2018-10-07T07:18:04.757 回答
3

No doubt @om-nom-nom provided a concise, correct answer. However, it will throw an exception for an empty list.

EDIT #2 Given my first edit, it's worthwhile to re-write my original, flawed answer:

def max[A](list: List[(A, Int)]): Option[Int] = list match  {
    case Nil => None
    case x :: xs => { val result = xs.foldLeft(x._2) { // acc = first item in list                                        
                              (acc, elem) => if(elem._2 > acc) elem._2 else acc 
                      }
                      Some(result)
                    }
} 

Note: I'm guessing that scalaz would let you use a more generic Num-like type instead of Int, but I haven't worked with it at all.

Testing

scala> val list = List(('a',10),('b',2),('c',3))
list: List[(Char, Int)] = List((a,10), (b,2), (c,3))

scala> max(list)
res5: Option[Int] = Some(10)

scala> val list: List[(String, Int)] = Nil
list: List[(String, Int)] = List()

scala> max(list)
res6: Option[Int] = None

EDIT For picking a start value, I decided to edit my answer after talking with @DustinGetz.

Picking Int.MinValue might not be a good choice as it's dependent on the particular OS/system on which the app is running.

I would argue that the first element in the list should be the start value. However, there's a potential run-time exception if the list is empty.

Please take a look at this post for more discussion - https://stackoverflow.com/a/23184020/409976.

于 2014-07-27T19:01:12.367 回答