19

I am trying to pull the maximum value form a map along with its key. For example:

val map = Map('a' -> 100, 'b' -> 23, ... 'z' -> 56)

Where 100 is the largest value, how would I go about pulling ('a',100)? I essentially want to use Map.max but search by value rather than key.

0__
  • 66,707
  • 21
  • 171
  • 266
pmaurais
  • 734
  • 2
  • 9
  • 30

2 Answers2

37

You can use maxBy with a function from the key-value pair to just the value:

val map = Map('a' -> 100, 'b' -> 23, 'z' -> 56)

map.maxBy(_._2)  // (a,100)

This is a short form for

map.maxBy { case (key, value) => value }
0__
  • 66,707
  • 21
  • 171
  • 266
  • Perfect, that works! I do have to ask, where are you getting the syntax for the predicate passed to maxBy()? – pmaurais Sep 26 '16 at 22:18
  • 1
    If you look into the [API docs](http://www.scala-lang.org/api/current/#scala.collection.Map), you find for `Map[A, B]`: `def maxBy[C](f: ((A, B)) ⇒ C)(implicit cmp: Ordering[C]): (A, B)` - the doc formatting is broken, I'm afraid, so I wrote the correct form here with a fresh type parameter `C`. So you pass a function from the tuple of (key, value) to any other value for which an ordering exists. `map.maxBy(_._2)` then is just the short form for `map.maxBy { case (key, value) => value }`. – 0__ Sep 26 '16 at 22:31
  • Hi, what about if 100 is present for more than one key? Is it possible to get all values instead of just one? Thanks! – Victor Aug 12 '18 at 12:34
  • @Victor You'd determine the maximum value first and then filter the map; e.g. `val map = Map('a' -> 100, 'b' -> 23, 'z' -> 56, 'c' -> 100); val maxVal = map.valuesIterator.max; map.filter(_._2 == maxVal)` – 0__ Aug 13 '18 at 14:01
3

A slight modification in case the max value you are looking for is present more than once in the map:

// Find the entries with the max value in the map
val maxValue = map.maxBy(item => item._2)

// Filter the map and retain the entries with the max value
map.filter(item => item._2 == maxValue._2)
Victor
  • 2,450
  • 2
  • 23
  • 54