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.

  • Not every map is reversible -- sometimes there may be duplikate values – kurunve Aug 3 '16 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 Aug 3 '16 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. – Jacob Raccuia Aug 3 '16 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 Aug 3 '16 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. – Jacob Raccuia Aug 3 '16 at 15:26
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>
| improve this answer | |
  • Keith -- note also salesforce.stackexchange.com/q/70302/2602 wherein VF now returns maps in sorted key order (something I just learned) – cropredy Aug 3 '16 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 Aug 3 '16 at 17:59
  • for VF or in Apex? the post I linked to suggested that VF will do the sorting (!?!) – cropredy Aug 3 '16 at 18:02
  • @cropredy Should have read it more carefully. I'll give it a quick go and add a PPS... – Keith C Aug 3 '16 at 18:03
  • I think it's PPS, not PSS. Post-post-script, not post-script-script. – Adrian Larson Aug 3 '16 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.

| improve this answer | |
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--;



}
| improve this answer | |
  • this is good to know, but I've added an example and it won't actually help :( – Jacob Raccuia Aug 3 '16 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;
}
| improve this answer | |
  • I will try this and report back – Jacob Raccuia Aug 3 '16 at 15:42

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.