2014-09-04 3 views
5

J'ai un Map<String,Integer> dont les entrées (clés) doivent être triées par ordre de valeur décroissante. Par exemple, si la carte ressemble à:Tri des valeurs de carte dans l'ordre décroissant avec Groovy

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

Le après le tri, il doit ressembler:

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

Ma meilleure tentative jusqu'ici:

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} 
} 

Quand je lance test() I obtenir la sortie suivante:

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. 

Où est-ce que je me trompe ici?

+0

Vous voulez dire trier les valeurs? Pas les clés comme dans la question? –

Répondre

12

Il suffit de faire:

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

Une autre option est juste: 'm.sort {-it.value}' – Steinar

+0

@tim_yates salut, pourriez-vous expliquer ce que cette fermeture signifie un, b -> b.value <=> a.value .. merci :) – user3714598

+0

@ user3714598, '<=>' est l'opérateur de "vaisseau spatial". Il délègue à la méthode 'compareTo'. Voir [ici] (http://docs.groovy-lang.org/latest/html/documentation/index.html#_spaceship_operator) pour la documentation. – AutonomousApps

1

Pour faire le tri, la mise en œuvre de Tim est le chemin à parcourir. Mais si vous vous demandez simplement pourquoi votre exemple de code ne fonctionne pas comme prévu, la réponse est que la variable 'triée' doit être de type LinkedHashMap, plutôt que simplement HashMap. Vous pouvez définir explicitement:

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

Ou, il suffit de faire ceci:

Map<String,Integer> sorted = [:] 
Questions connexes