Click here to Skip to main content
15,887,246 members
Please Sign up or sign in to vote.
0.00/5 (No votes)
I am sorting a list of objects according to a variable stored in them. Lets name that variable "sortCriteria" 
A sample set of "sortCriteria" values for different objects : 

400, 329, 529, "String1", 678, "String2", 588, "String3", "String1",  201, "String2"

So, basically there are 4 kind of values I can get in "sortCriteria" :
1. A numeric value
2. String1
3. String2
4. String3

Now I have to sort this data in such a way that the numeric data should be given the most priority, then "String1",  then "String2" & then "String3". i.e. 
Priority of (Numeric > String1 > String2 > String3)
Note that, in output, all those numeric values should be in sorted order.

Hence, the sorted order of sample data would be -
201, 329, 400, 529, 588, 678, "String1", "String1", "String2", "String2", "String3". 
Also, if multiple objects are having same "sortCriteria" values, their order should be retained.
Eg. 
Let say I got 2 objects whose "sortCriteria" value is same 
Object 1 : 205,
Object 2 : 205.
Then in sorted order Object1 should come before Object2. 


What I have tried:

My current Javascript implementation of sorting specific logic looks like this : 

    function mySortRule(a, b) {
             var value1 = a[1], value2 = b[1];
             var value1Priority = getPriorityOf(value1);
             var value2Priority = getPriorityOf(value2);
             return value1Priority - value2Priority;
    }
    function getPriorityOf(value) {
             var priority;
             if(value!="String1" && value!="String2" && value!="String3") {
                 priority = value;
             }
             else if(value == "String1") {
                priority = Number.MAX_VALUE-2;
             }
             else if(value == "String2") {
                priority = Number.MAX_VALUE-1;
             }
             else if(value == "String3") {
                priority = Number.MAX_VALUE;
             }
             return priority;
    }
    sortCriteriaArray.sort(mySortRule);
sortCriteriaArray[i] value is in this format : 
["indexOfObject", "sortCriteria"]"
My solution is kind of working but it's not retaining the objects order. Also, I don't feel that this is a good approach because -
1. Tomorrow, let say we have to fit in some other types of strings. In that case, we will have to change these conditional statements in getPriorityOf() function.
2. Using "Number.MAX_VALUE" to set the priority looks hacky to me.
Can there be any better way to achieve this?
Posted
Updated 22-Jan-19 3:45am

1 solution

Usually, the sorting methods expect that the comparison method returns simply a 0 when two items are equal, any negative value when the first is less than the second and a positive value when the first is greater then the second. The method will not build up a collection of comparison results; it will instead evaluate each result to determine whether to swap the two compared items and will repeat until all necessary comparisons have been performed.

I'm not expert enough with javascript to post some code, but the following could help:
You are treating each item not as a single value/object, but as a pair of objects, where the first object is the item's type and the second is the item itself.
For each pair of items (a and b) you should compare the types of the two items and then, if they are equal, compare the items themself.

Some pseudo-code of mySortRule could be
if (value1 == value2)
    return 0;

var priority1 = getPriorityOf(value1);
var priority2 = getPriorityOf(value2);

var result = priority1.CompareTo(priority2);
if (result != 0)
    return result;

result = value1.CompareTo(value2);
if (result != 0)
    return result;

return 0;

together with a possible getPriorityOf like
if (value is numeric)
    return 1;
if (value is string)
    return 2;

//

return Number.MAX_VALUE;
 
Share this answer
 

This content, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)



CodeProject, 20 Bay Street, 11th Floor Toronto, Ontario, Canada M5J 2N8 +1 (416) 849-8900