You need to sign in to do that
Don't have an account?

Sorting a Map by Value
Hi,
I would like to know if we can sort a Map by Value. I have a Map like below.
Map<Id, Integer> accMap = new Map<Id, Integer>();
e.g I have values in the Map like below
accMap.put('Id1' , 2);
accMap.put('Id2' , 1);
accMap.put('Id3' , 4);
accMap.put('Id4' , 3);
accMap.put('Id5' , 5);
Now i want the Map to be sorted by the Integer value and my output should be like below
accMap.put('Id5' , 5);
accMap.put('Id3' , 4);
accMap.put('Id4' , 3);
accMap.put('Id1' , 2);
accMap.put('Id2' , 1);
Any help will be appriciated.
Thanks
Bramha
Map do not hae sorting supported, they are a key value pair collection. Now for your issue you need a sorting algo to work and create a list of key according to the order you want. You can use linear search algo or bubble sort from data structure. Please ask if any issue.
All Answers
Maps don't really have a concept of sort order. If you want to maintain order, I think you'll have to use a List.
Map do not hae sorting supported, they are a key value pair collection. Now for your issue you need a sorting algo to work and create a list of key according to the order you want. You can use linear search algo or bubble sort from data structure. Please ask if any issue.
Hi,
Thnaks for the reply guys...Is there any sort of example or brief code which covers this senario. It would be really helpful.
Thanks
Bramha
Sorting on map is not possible. But if you want to sort map with there key then we can do something like this :
Please note above code will sort the map on their key and NOT values.
Thanks
Ankit Arora
Blog | Facebook | Blog Page
Ankit
I got this error with your code.
Error: Compile Error: expecting a right parentheses, found 'Id2' at line 4 column 11
accMap.put('Id2',2);
I got this error....
Muruganand_Sforce
Would love to see your code as am amazed that the above code is working absolutely perfect for me and not for you.
Have you done any changes?? Please post your code here.
Thanks
Ankit Arora
Blog | Facebook | Blog Page
Public class mapsort
{
map<String , Integer> accMap = new Map<String,Integer>();
accMap.put('Id2',2);
accMap.put('Id1',1);
accMap.put('Id4',4);
accMap.put('Id3',3);
accMap.put('Id5',5);
List<String> aList = new List<String>();
aList.addAll(accMap.keySet());
aList.sort();
//so here you will get sorted total base on key
for(String a: aList)
{
System.debug( '::::::::::::: ' + accMap.get(a)) ;
}
}
You need to do this in constructor or in any method like try this :
Thanks
Ankit Arora
Blog | Facebook | Blog Page
Hi Ankit,
Thank you very much. I know we can sort Maps based on the Keys, but i was looking for a solution which could sort the Maps by their Value.
Thanks
Bramha
Hi Sharma,
Thanks for the idea, i guess we can do it with sorting techniques(bubble sort or linear sort). I was wondering if it would be a efficient way of the dataset is large. I came across a way which would work out.
1) reverse the Map into i.e Map<Integer, List<Id>>
2) And then sort this Map on the key set.
I guess this would work in my case. Have to check this now. Will get back to you once i am done.
Thanks
Bramha
Bhrama,
Here is the code to get sorted values( in both Ascending and Descending) of a map:
Regards,
Lakshman
Hi Bramha,
I know this way that I suggested will excute a lot of script statement, but I don't see any other option. I am also waiting to see your code. I will my self will try find a better solution.
Hi Lakshman,
Thanks for the reply. i guess you didn't get my question correctly. I want the output as a Map rather than a List<Integers>.
Thanks
Bramha
Bramha1, a sorted map makes no sense and you can't have one.
You may have the keys of the map sorted by the values, or the values by the keys, or the keys sorted alone, or the values sorted alone, etc. but you may not have a sorted map.
When you say you "want the output as a map" what do you mean? Do you simply want a the current map of A,B key-value pairs turned into a map of B,A Key value pairs? You can have that (although duplicates in the values may cause you grief because they will become duplicate keys and you may lose data, etc.).
So, would you care to clarify what your goal is? Is the confusion about the storage in Apex of the data that you want to create, or is there some output format you're striving for?
Inquiring minds! Best, Steve.
I know your requirement buddy. This is just a work around to get values of a Map sorted in form of List as there is no API available to sort the Map in Apex.
One more thing you can do is put the values in Map in ordered way. :)
Let me know if you are done with building your algorithm.
-Lakshman
You can't add values into a Map in an ordered way. It doesn't not matter what order you enter them, once they are in the map they are unordered by definition. A map has no intrinsic order.
And, if you just want the values of the Map in a sorted List, you can just say
Map<String, Integer> x = ... whatever
List<Integer> sortedValues = x.values().sort().
Best, Steve.
Hi Bramha,
I sorted a MAP I think so , please verify it
I would definitly like this to work and marked as aceepted solution. Pease let me know is that you want.
Shashikant,
Your code fails when any two values in Map are same.
-Lakshman
Hi Sharma,
Will this work for the below Map.
accMap.put('ID1' , 20);
accMap.put('ID2' , 10);
accMap.put('ID3' , 40);
accMap.put('ID4' , 30);
accMap.put('ID5' , 50);
accMap.put('ID6' , 30);
accMap.put('ID7' , 40);
accMap.put('ID8' , 50);
Thanks
Bramha
Hi Steve,
I want the Keys to be sorted based on the Values(desc order like 10, 9, 8,7,6,5,4,3,2,1). After i am done with sorting i need to get the top 5 Values(10,9,8,7,6) Ids .
If you want any more info please do ask.
Thanks
Bramha
If you are fetching this from query then instead of creating a map you should write the query accordingly. Like use DESC on your integer value in query and get the 5 records using Limit.
Thanks
Ankit Arora
Blog | Facebook | Blog Page
Hi All,
I have figured out the way and solved this issue. Thanks all of you guys who contributed as your ideas led to my result.
Once again thanks for the help.
Cheers
Bramha
Bramha,
Curious to know your way.
-Lakshman
}
Hi,
I haven't got the output as a Map but could get the exact thing what i wanted in the order of the Value.
public void getTopDownlaodDocumentsForAccount(Id id) {
List<Research_Aggregator_Download__c> downloads = [Select Id,Name,Research_Aggregator_Document__c, Research_Aggregator_Document__r.Research_Id__r.Id fromResearch_Aggregator_Download__c where Research_Aggregator_Account__r.Account__r.Id=: id];
accountMap = new Map<Id, Integer>();
if(downloads.size() > 0) {
for(Research_Aggregator_Download__c r : downloads) {
if(accountMap.containsKey(r.Research_Aggregator_Document__r.Research_Id__r.Id)) {
accountMap.put(r.Research_Aggregator_Document__r.Research_Id__r.Id, accountMap.get(r.Research_Aggregator_Document__r.Research_Id__r.Id)+1);
}else{
accountMap.put(r.Research_Aggregator_Document__r.Research_Id__r.Id, 1);
}
}
}
if(accountMap.size() > 0) getTopTenAccountDocumentDetails();
}
public void getTopTenAccountDocumentDetails() {
Map<Integer, Set<Id>> newMap = new Map<Integer, Set<Id>>();
Set<Id> accountIds = new Set<Id>();
accountList = new List<String>();
List<Integer> values = new List<Integer>(accountMap.Values());
for(Id accid : accountMap.keySet()) {
if(newMap.containsKey(accountMap.get(accid))) {
accountIds = newMap.get(accountMap.get(accid));
accountIds.add(accid);
newMap.put(accountMap.get(accid) ,accountIds );
} else{
accountIds = new Set<Id>();
accountIds.add(accid);
newMap.put(accountMap.get(accid) , accountIds);
}
}
values.sort();
List<Integer> descValues = new List<Integer>();
for(Integer i = values.size()-1 ; i >= 0 ; i--) {
descValues.add(values.get(i));
}
Set<Id> Ids = new Set<Id>();
Set<Id> sortedIds = new Set<Id>();
Set<Id> idList = new Set<Id>();
for(Integer i : descValues) {
sortedIds = newMap.get(i);
idList.addAll(sortedIds);
if(idList.size() < 10 && !Ids.containsAll(sortedIds)) {
if(sortedIds.size() > 0) {
for(Id sorted : sortedIds) {
if(accountList.size() < 10)
accountList.add(sorted +','+ i);
}
}
}
Here i am using the accountList and getting the top 10 Values and in the next bit i am using a split to have the Id and the Integer Value.
NB: If you guys any sort of ideas to customize the code, please let me know.
Cheers
Bramha
map<String , Integer> aMap = new Map<String,Integer>() ;
map<String , Integer> accMap = new Map<String,Integer>() ;
accMap.put('Id2' , 2);
accMap.put('Id1' , 1);
accMap.put('Id4' , 4);
accMap.put('Id3' , 3);
accMap.put('Id5' , 5);
List<String> aList = new List<String>();
List<integer> values = new List<integer>();
aList.addAll(accMap.keySet());
for(String str:aList)
{
values.add(accMap.get(str));
}
values.sort();
for(integer a: values)
{
for(String s:aList)
{
Integer j=accMap.get(s);
if(j==a)
{
aMap.put(s,j);
}
}
}
System.debug(aMap);
I know the complexity is greater in this case , but might be helpful with small Map
Input : collection of couple stored in map : A as key and B as value
Output : collection of couple sorted by value
In my case, here is the map
the context of my application fills the map...
Here are the declaration to store ordered result :
consultantSet contains all the keys
Bubble sort
I hope this sample code can help.
In apex to short a map we need to use wrapper class and comparable interface
For more details go to :http://himanshurana.in/http-himanshurana-in-sort-map-in-apex-