+ Start a Discussion
GtemporaoGtemporao 

Sorting a Nested Map

Hello,

 

I have a data structure of the type Map<String,Map<String,Decimal>>, which relates each customer to a list of bank accounts and their respective balances, as well as a total balance which would be the sum of all balances.

 

A sample line of this structure is something like the following:

 

"John" -> ("Bank 1" -> 1200.00, "Bank 2" -> 300.50, "Total" -> 1500.50)

 

I would like to sort this structure by the "Total" value. Can you please give me some ideas?

 

Thank you!

Best Answer chosen by Admin (Salesforce Developers) 
Saikishore Reddy AengareddySaikishore Reddy Aengareddy

Even if you sort the map somehow by total the map will be always sorted by default on "Keys"

Lets say you have

"John" -> ("Bank 1" -> 1200.00, "Bank 2" -> 300.50, "Total" -> 1500.50)

"Brian" -> ("Bank 1" -> 1200.00, "Bank 2" -> 300.50, "Total" -> 1100.50)

"Aaron" -> ("Bank 1" -> 1200.00, "Bank 2" -> 300.50, "Total" -> 1900.50)

 

lets say you want to sort ascending on total and you would expect Brian, John and Aaron but the map will always have Aaron, Brian and John.. Its sorted by default.

 

Here is the sample code for your structure sorting and see if it helps... Run it in Developer console and see the logs

 

Map<String,Map<String,Decimal>> bankMap = new Map<String,Map<String,Decimal>>{'John' => new Map<string,Decimal>{'Bank 1' => 1200.00, 'Bank 2' => 300.50, 'Total' => 1500.50},
    'Brian'=> new Map<string,Decimal>{'Bank 1'=>100.00, 'Bank 2'=>200.00,'Bank 3'=>300,'Total'=>600.00},
     'Lara'=> new Map<string,Decimal>{'Bank 1'=>100.00, 'Bank 2'=>200.00,'Bank 3'=>300,'Total'=>900.00}   };
//Create a temp map with key as total and above map key as List of strings
Map<Decimal,List<String>> tempMap = new Map<Decimal,List<string>>();
Map<String,Map<String,Decimal>> bankMapSorted = new Map<String,Map<String,Decimal>>();
for(String s : bankMap.keySet()){
    List<string> stringList = new List<String>();
    if(!tempMap.containsKey((bankMap.get(s)).get('Total'))){
        stringList.add(s);
        tempMap.put((bankMap.get(s)).get('Total'),stringList);
    }else{
    	stringList = tempMap.get((bankMap.get(s)).get('Total'));
        stringList.add(s);
        tempMap.put((bankMap.get(s)).get('Total'),stringList);
    }
}
List<decimal> totalsList = new List<decimal>();
totalsList.addall(tempMap.keyset());
system.debug('SortedLIst@@@@'+totalsList);
totalsList.sort();//sorts in ascending order
for(Integer i = 0; i<totalsList.size();i++){
    for(string s : tempMap.get(totalsList.get(i))){
    	system.debug('@@@@ Order '+ (i+1)+'  Key -->'+s+'  Value-->'+ bankMap.get(s));
    }
}

 

 

All Answers

Saikishore Reddy AengareddySaikishore Reddy Aengareddy

Even if you sort the map somehow by total the map will be always sorted by default on "Keys"

Lets say you have

"John" -> ("Bank 1" -> 1200.00, "Bank 2" -> 300.50, "Total" -> 1500.50)

"Brian" -> ("Bank 1" -> 1200.00, "Bank 2" -> 300.50, "Total" -> 1100.50)

"Aaron" -> ("Bank 1" -> 1200.00, "Bank 2" -> 300.50, "Total" -> 1900.50)

 

lets say you want to sort ascending on total and you would expect Brian, John and Aaron but the map will always have Aaron, Brian and John.. Its sorted by default.

 

Here is the sample code for your structure sorting and see if it helps... Run it in Developer console and see the logs

 

Map<String,Map<String,Decimal>> bankMap = new Map<String,Map<String,Decimal>>{'John' => new Map<string,Decimal>{'Bank 1' => 1200.00, 'Bank 2' => 300.50, 'Total' => 1500.50},
    'Brian'=> new Map<string,Decimal>{'Bank 1'=>100.00, 'Bank 2'=>200.00,'Bank 3'=>300,'Total'=>600.00},
     'Lara'=> new Map<string,Decimal>{'Bank 1'=>100.00, 'Bank 2'=>200.00,'Bank 3'=>300,'Total'=>900.00}   };
//Create a temp map with key as total and above map key as List of strings
Map<Decimal,List<String>> tempMap = new Map<Decimal,List<string>>();
Map<String,Map<String,Decimal>> bankMapSorted = new Map<String,Map<String,Decimal>>();
for(String s : bankMap.keySet()){
    List<string> stringList = new List<String>();
    if(!tempMap.containsKey((bankMap.get(s)).get('Total'))){
        stringList.add(s);
        tempMap.put((bankMap.get(s)).get('Total'),stringList);
    }else{
    	stringList = tempMap.get((bankMap.get(s)).get('Total'));
        stringList.add(s);
        tempMap.put((bankMap.get(s)).get('Total'),stringList);
    }
}
List<decimal> totalsList = new List<decimal>();
totalsList.addall(tempMap.keyset());
system.debug('SortedLIst@@@@'+totalsList);
totalsList.sort();//sorts in ascending order
for(Integer i = 0; i<totalsList.size();i++){
    for(string s : tempMap.get(totalsList.get(i))){
    	system.debug('@@@@ Order '+ (i+1)+'  Key -->'+s+'  Value-->'+ bankMap.get(s));
    }
}

 

 

This was selected as the best answer
GtemporaoGtemporao

@Sam_SFDC15: Thank you very, very much. This has not entirely solved my problem but it was enough so I could take over from where you left. I really don't understand why Apex does not allow custom sorting of maps ...