Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Sorting an array of objects specifying sort criteria as a string

I would like to have a function to sort an array of objects by getting a string as input that include the name of the property and sort direction. I need something like this :

var myArray = [{name:"A", age: 30}, {name:"B", age:20}, {name:"C", age:20}];

var strSort = "age asc, name desc";

var sortedArray = customSortFuntion(myArray,strSort);
//sortedArray == [{name:"C", age:20}, {name:"B", age:20},{name:"A", age: 30}]

function customSortFuntion(myArray,strSort)
{
 //return sorted by age asc and sorted by name desc etc..??
}
like image 203
Alborz Avatar asked Jan 22 '14 07:01

Alborz


People also ask

How do you sort an array of strings?

There are two ways to sort a string array in Java: Using User-Defined Logic. Using the Arrays. sort() Methodm.

How do you sort an array of objects based on a property?

Example 1: Sort Array by Property NameThe sort() method sorts its elements according to the values returned by a custom sort function ( compareName in this case). Here, The property names are changed to uppercase using the toUpperCase() method. If comparing two names results in 1, then their order is changed.

How do you sort an array with two conditions?

The sort() callback function usually receives two arguments, say a and b, which are nothing but two elements of the array on which sort() was called and the callback function runs for each possible pair of elements of the array.


1 Answers

This solution requires Array.prototype.map ("shim"-able) to present:

function customSortFunction(myArray,strSort){
    var sorts=strSort.split(",").map(function(v,i){
        var o=v.match(/\s(asc|desc)$/i);
        if(o){
            return {"prop":v.replace(/\s(asc|desc)$/i,"").replace(/^\s+|\s+$/,""),"order":o[1].toLowerCase()};
        }else{
            return {"prop":v,"order":"asc"};
        }
    });
    myArray.sort(function(a,b){
        var av,bv;
        for(var i=0;i<sorts.length;i++){
            av=a[sorts[i]["prop"]] || 0;
            bv=b[sorts[i]["prop"]] || 0;
            if(sorts[i]["order"]=="asc"){
                if(av>bv){
                    return 1;
                }else if(bv>av){
                    return -1;
                }
            }else{
                if(av>bv){
                    return -1;
                }else if(bv>av){
                    return 1;
                }
            }
        }
        return 0;
    });
    return myArray;
}

Online demo

Given this array:

[
    {name:"Z", age: 6}, 
    {name:"Z", age: 19}, 
    {name:"A", age: 30}, 
    {name:"B", age: 20}, 
    {name:"C", age: 20}, 
    {name:"A", age: 31}
]

and sort order name asc, age desc,

gives this output:

[ { name: 'A', age: 31 },
  { name: 'A', age: 30 },
  { name: 'B', age: 20 },
  { name: 'C', age: 20 },
  { name: 'Z', age: 19 },
  { name: 'Z', age: 6 } ]
like image 145
Passerby Avatar answered Oct 06 '22 00:10

Passerby