5

How can I loop through a Map or List in reverse order in VF?

or

Can I reverse the order of a map in Apex?

Here is my code:

    String nsp = PackageUtils.namespacePrefix; 
    Map<String, String> fieldset = new Map<String, String>();

    List<Schema.FieldSetMember> fieldSetMemberList = getFieldSet(nsp + 'Search_Table', nsp + objectName);

    for(Schema.FieldSetMember fieldSetMemberObj : fieldSetMemberList) {
            fieldset.put(fieldSetMemberObj.getFieldPath(), fieldSetMemberObj.getLabel());
    }

Here is the VF:

  <apex:repeat value="{!fieldset}" var="field">
        <th>{!fieldset[field]}</th>                
  </apex:repeat>

This shows Description, Id, Name in VF, but I want to show Name, Id, Description.

6
  • Not every map is reversible -- sometimes there may be duplikate values
    – kurunve
    Commented Aug 3, 2016 at 15:11
  • 1
    Can you explain more about what you are attempting to accomplish? Maps aren't an ordered collection, so there is no 'order' to be reversed.
    – Derek F
    Commented Aug 3, 2016 at 15:21
  • @DerekF I am looping through a map in my VF and the order is the reverse order of what I want. If I flipped the map, then it would be in the correct order. Commented Aug 3, 2016 at 15:22
  • You can't loop over maps directly, so you're either looping over the map's keySet (which is a Set<Object>, and similarly unordered), or over the map's values. What is the type of your map? Is it something like Map<Id, List<sObject>>?
    – Derek F
    Commented Aug 3, 2016 at 15:25
  • @DerekF I've added an example that shows, it's Map<String, String> and yeah, I guess I"m looping the keyset. Commented Aug 3, 2016 at 15:26

4 Answers 4

9

If you want the keys in a defined order, the simplest approach is shown in PPS below.

Before knowing that I would have said to put them in a list and then sort them:

public List<String> fields {get; private set;}

    ...
    fields = new List<String>(fieldSet.keySet());
    fields.sort();
    ...

then iterate over the sorted list in the Visualforce while still accessing the values from the map:

<apex:repeat value="{!fields}" var="field">
    <th>{!fieldSet[field]}</th>                
</apex:repeat>

PS

Just did a quick test to see what the change to a deterministic order for map keys might be and by observation from this code at least:

Map<String, String> m = new Map<String, String>{
    'c' => 'c',
    'd' => 'd',
    'b' => 'b'
};
m.put('a', 'a');
for (String s : m.keySet()) {
    System.debug(s);
}

the order was insertion order (not alphabetic sort order) like Java's LinkedHashMap.

PPS

And surprisingly a Visualforce apex:repeat sorts the keys alphabetically:

public class Tmp {
    public Map<String, String> m {get; set;}
    public Tmp() {
        m = new Map<String, String>();
        m.put('c', 'c');
        m.put('d', 'd');
        m.put('b', 'b');
        m.put('a', 'a');
    }
}
<apex:page controller="Tmp">
    <apex:repeat value="{!m}" var="k">
        {!k}<br/>
    </apex:repeat>
</apex:page>
7
  • Keith -- note also salesforce.stackexchange.com/q/70302/2602 wherein VF now returns maps in sorted key order (something I just learned)
    – cropredy
    Commented Aug 3, 2016 at 17:19
  • @cropredy In my quick test the keys were returned in insertion order. Don't know if that is always the case though.
    – Keith C
    Commented Aug 3, 2016 at 17:59
  • for VF or in Apex? the post I linked to suggested that VF will do the sorting (!?!)
    – cropredy
    Commented Aug 3, 2016 at 18:02
  • @cropredy Should have read it more carefully. I'll give it a quick go and add a PPS...
    – Keith C
    Commented Aug 3, 2016 at 18:03
  • I think it's PPS, not PSS. Post-post-script, not post-script-script.
    – Adrian Larson
    Commented Aug 3, 2016 at 19:08
2

Maps in Apex are an example of an unordered collection. Since Summer '15, the iteration order of unordered collections (maps and sets) are deterministic, but it's still impossible to impose a specific order on these collections.

That's true for sObjects at least. If you have an apex class, and implement equals() and hashcode() methods, you may be able to control the iteration order to some degree.

Generally speaking, if you want to specify the order of items in a collection (or if you depend on the ordering), you need to use a list.

The List class does contain a sort() method, but that only sorts in ascending order, and what exactly 'ascending` order means is not well defined (to the best of my knowledge).

Abhijeet's answer is one way to reverse the order of an existing list (just initialize a second list and add to it on each iteration if you need to use the reversed order somewhere else in your code).

The generally more reliable method, however, would be to insert items into a list in the order you need in the first place (within your getFieldSet() method, if possible). Or, if appropriate, you can include ORDER BY <field name> [ASC/DESC] in a query.

1

Don't know about maps but in order to read lists in reverse order, you can see the below code i made:

list<integer> lst = new list<integer>();
lst.add(1);
lst.add(2);

system.debug('## '+lst);

integer a =lst.size();
while(a>0){


    system.debug('--> '+lst[a-1]);    

    a--;



}
1
  • this is good to know, but I've added an example and it won't actually help :( Commented Aug 3, 2016 at 15:42
0

Not every map can be reversed to map (because of duplicate values for different keys), but it can be reversed to map of lists. For example, for Map<String, String> next sample code can be used:

Map<String, List<String> > reverseMap(Map<String, String> original_map){
    Map<String, String> original_map;
    Map<String, List<String> > reversed_map = new Map<String, List<String>>();
    for(String key : original_map.keySet()){
        String original_map_value = original_map.get(key);
        if (!reversed_map.contains(original_map_value)){
            reversed_map.put(original_map_value, new List<String>());
        }
        reversed_map.get(original_map_value).add(key);
    }
    return reversed_map;
}
1
  • I will try this and report back Commented Aug 3, 2016 at 15:42

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .