masterdany88 masterdany88 -4 years ago 162
Scala Question

Iterate over map with index and original order in Scala template in PlayFramework2. How to pick up the one after currently iterated?

I am trying to loop over a map in scala template in playFramework2.2.
Here is the code for that:

<ol>
@for(((key, value), currentIndex) <- m.myMap.zipWithIndex) {
<li>@key - @value - @currentIndex</li>
}
</ol>


map declaration in java:

Map myMap = new HashMap<String, Integer>();


map declaration in scala:

meters: List[intranet.controllers.Index.Meter]


And I've sorted that map (by value) already with java method as follow:

public static Map sort(Map unsortMap, Order order) {
List list = new LinkedList(unsortMap.entrySet());


comparator = new Comparator() {
public int compare(Object o1, Object o2) {
return ((Comparable) ((Map.Entry) (o1)).getValue()).compareTo(((Map.Entry) (o2)).getValue());
}
}

Collections.sort(list, comparator);

Map sortedMap = new LinkedHashMap();
for (Iterator it = list.iterator(); it.hasNext();) {
Map.Entry entry = (Map.Entry) it.next();
sortedMap.put(entry.getKey(), entry.getValue());
}
return sortedMap;
}


Unfortunately my problem is that I iterate over a map with
zipWithIndex
method I loose my order.

Here is current result:

Key - Value - Index
WA - 41 - 4
BA - 66 - 0
BM - 52 - 2
DP - 0 - 6
JTM - 0 - 7
TN - 59 - 1
WP - 46 - 3
SM - 0 - 5


As You can see it is not ordered, but it should be that way:

Key - Value - Index
BA - 66 - 0
TN - 59 - 1
BM - 52 - 2
WP - 46 - 3
WA - 41 - 4
SM - 0 - 5
DP - 0 - 6
JTM - 0 - 7


So question are:


  1. How to iterate over a map with index with original order?



I figure out first question. Here is working loop code:

@for(((key, value), currentIndex) <- m.lastMonthRanking.view.zipWithIndex) {
<li>
<span @if(session().get("email").equals(key)){ class="label label-info" style="font-size: 100%; display: grid"}>@key
<span class="badge">@value</span>
</span>
</li>
}



  1. How to access the next/previous element after/before the one it is currently iterated?






Edit

I have a map, where key is
@userName
(String) and
@value
is (Integer).
I wanna print list
<ol><li>@userName (@value)</li></ol>
ordered by
@value
. If value is repeated in many users I would like to print those element in other way, so I have to know is next/previous element in the list has the same value. Normally in java with list I would do something like that:

for (int i = 0; i < CrunchifyList.size(); i++) {
System.out.println(CrunchifyList.get(i-1) + " is previous element");
System.out.println(CrunchifyList.get(i) + " is current element");
System.out.println(CrunchifyList.get(i+1) + " is next element");
}


But now I need to do this in scala and with map.
Please help

Answer Source

As for first question, you should use a map that maintains the insertion order. One example is the scala.collection.immutable.ListMap.

@ import scala.collection.immutable.{HashMap, ListMap}
import scala.collection.immutable.{HashMap, ListMap}
@ val l = 1 to 5
l: collection.immutable.Range.Inclusive = Range(1, 2, 3, 4, 5)
@ val hm = HashMap(l.zipWithIndex: _*)
hm: HashMap[Int, Int] = Map(5 -> 4, 1 -> 0, 2 -> 1, 3 -> 2, 4 -> 3)
@ val lm = ListMap(l.zipWithIndex: _*)
lm: ListMap[Int, Int] = Map(1 -> 0, 2 -> 1, 3 -> 2, 4 -> 3, 5 -> 4)
Recommended from our users: Dynamic Network Monitoring from WhatsUp Gold from IPSwitch. Free Download