简体   繁体   中英

Sorting Map values in descending order with Groovy

I have a Map<String,Integer> whose entries (keys) need to be sorted in order of descending value . For instance, if the map looks like:

"a" => 5
"b" => 3
"c" => 12
"d" => 9

The after sorting it needs to look like:

"c" => 12
"d" => 9
"a" => 5
"b" => 3

My best attempt thus far:

def test() {
    Map<String,Integer> toSort = new HashMap<String,Integer>()
    toSort.put("a", 5)
    toSort.put("b", 3)
    toSort.put("c", 12)
    toSort.put("d", 9)

    Map<String,Integer> sorted = sortMapDesc(toSort)
    sorted.each {
        println "${it.key} has a value of ${it.value}."
    }
}

def sortMapDesc(Map<String,Integer> toSort) {
    println "Sorting..."
    println toSort

    // The map of properly sorted entries.
    Map<String,Integer> sorted = new HashMap<String,Integer>()

    // Keep scanning the map for the key with the highest value. When we find
    // it, add it as the next entry to the 'sorted' map, and then zero it out
    // so it won't show up as the highest on subsequent scans/passes. Stop scanning
    // when the entire 'toSort' map contains keys with zeros.
    while(!mapIsAllZeros(toSort)) {
        int highest = -1
        String highestKey = ""
        toSort.each {
            if(it.value > highest) {
                highest = it.value
                highestKey = it.key
            }
        }

        toSort.put(highestKey, 0)
        sorted.put(highestKey, highest)
    }

    sorted
}

def mapIsAllZeros(Map<String,Integer> toCheck) {
    toCheck.values().every{!it}
}

When I run test() I get the following output:

Sorting...
[d:9, b:3, c:12, a:5]
d has a value of 9.
b has a value of 3.
c has a value of 12.
a has a value of 5.

Where am I going wrong here?

Just do:

​def m = [a:​5, b:12, c:3, d:9]
def sorted = m.sort { a, b -> b.value <=> a.value }

To do the sorting, Tim's implementation is the way to go. But if you're just wondering why your example code doesn't work as you expect, the answer is that the variable 'sorted' needs to be of type LinkedHashMap, rather than just HashMap. You can set it explicitly:

Map<String,Integer> sorted = new LinkedHashMap<String,Integer>()

Or, just do this:

Map<String,Integer> sorted = [:]

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM