Atul Bhatia
Atul Bhatia

Reputation: 1795

How to sort scala maps by length of the key (assuming keys are strings)

I want to sort a scala map by key length. The map looks something like:

val randomMap = Map("short" -> "randomVal1", "muchlonger" -> "randomVal2")

I want to sort randomMap such that when I iterate over it, I will start with the longest key first...so it should iterate over the "muchlonger" element first.

Upvotes: 2

Views: 2249

Answers (2)

theon
theon

Reputation: 14420

One option would be to define a custom ordering for a TreeMap. TreeMap is a sorted implementation of Map

import scala.collection.immutable.TreeMap

implicit object LengthOrder extends Ordering[String] { 
    def compare(s1: String, s2: String) = s1.length - s2.length 
}

val randomMap = TreeMap("111" -> "111", "1" -> "1", "11" -> "11")

//randomMap: TreeMap[String,String] = Map(1 -> 1, 11 -> 11, 111 -> 111)

val keys = randomMap.keys
//keys: Iterable[String] = Set(1, 11, 111)

Note that this will affect all TreeMap[String]s where LengthOrder is in scope. In your project you could nest LengthOrder in another object (or put it in its own package) and then only import it inside the specific code blocks that need it.


Edit:

@Bharadwaj made a good point about how this would destroy all but one keys that have the same length. Something like this would fix this issue:

implicit object LengthOrder extends Ordering[String] { 
    def compare(s1: String, s2: String) = s1.length - s2.length match {
      case 0 => s1.compareTo(s2)
      case x => x
    }
}

Upvotes: 1

Shadowlands
Shadowlands

Reputation: 15074

Convert it to a sequence of key/value pairs and apply a sorting criteria. eg.:

randomMap.toSeq.sortBy(_._1.length).reverse

(reverse because it sorts by shortest to longest by default).

Upvotes: 3

Related Questions