Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Passing additional parameters in the compareFunction of .sort() method

The Approach

I am trying to create a custom method that will sort an array' objects with a parameter of my choice.

I have, for instance, the following array...

var albumList = [
   { value: 'A 2011', count: '18' },
   { value: 'Z 2012', count: '22' },
   { value: 'C 2012', count: '7' },
   { value: 'H 2013', count: '21' }
   // etc...
];

I managed to alphabetically sort this array by 'value' but with a limited functionality.

Array.prototype.alphaSort = function () {
    function compare(a, b) {
        if (a.value < b.value) // sorting by 'count'
            return -1;
        if (a.value > b.value) // sorting by 'count'
            return 1;
        return 0;
    }
    this.sort(compare);
}

Then by calling albumList.alphaSort(); everything works perfectly. However, the reason why I called it limited is the fact that I am not able to determine the parameter by which the array is going to be sorted. By default it is 'value' as it has been set above in the second code snippet.

Basically, what I am trying to do is to have something like albumList.alphaSort('count') that will allow the function to automatically conduct the sorting process based on 'count', or whatever I might have in future of additional keys and values, instead of going back and forth to change the whole code...

// .alphaSort('count') should be interpreted as follows

if (a.count < b.count) // sorting by 'value'
     return -1;
if (a.count > b.count) // sorting by 'value'
     return 1;

In other words, I need to pass an argument/parameter which I can implement at any time; thus, I can easily handle any errors derived from later changes. That being the case, the comparing logic would be...

a.MY_ARGUMENT < b.MY_ARGUMENT

I hope you got the idea of what I am looking for!


The Problem

As an attempt and for the sake of clarity (although it does not make any sense) I did as follows...

Array.prototype.alphaSort = function (sortParameter) {
     function compare(a, b) {
         if (a.sortParameter < b.sortParameter) 
             return -1;
         if (a.sortParameter > b.sortParameter)
             return 1;
         return 0;
    }
    this.sort(compare);
}

albumList.alphaSort('count');

This, obviously, will not pass 'sortParameter' to the compare function and, yet, compare(a,b) will not take any additional parameters.


Possible Duplicate

Any way to extend javascript's array.sort() method to accept another parameter?

like image 467
Simone Avatar asked Oct 21 '22 22:10

Simone


1 Answers

This worked for me:

    Array.prototype.alphaSort = function (sortParameter) {
        function compare(a, b) {
            function isNumeric(num){
                return !isNaN(num)
            }

            // convert string to numbers if necessary:
            // http://stackoverflow.com/questions/175739/is-there-a-built-in-way-in-javascript-to-check-if-a-string-is-a-valid-number
            var left = (isNumeric(a[sortParameter])) ? +a[sortParameter] : a[sortParameter];
            var right = (isNumeric(b[sortParameter])) ? +b[sortParameter] : b[sortParameter];

            if (left < right)
                return -1;
            if (left > right) 
                return 1;
            return 0;
        }
        this.sort(compare);
    }

    var albumList = [
       { value: 'A 2011', count: '18' },
       { value: 'Z 2012', count: '22' },
       { value: 'C 2012', count: '7' },
       { value: 'H 2013', count: '21' }

    ];

    albumList.alphaSort('count');
    console.log(albumList);

In Javascript, you can get object values using obj.value as well as obj[value].

like image 90
Param Avatar answered Nov 03 '22 03:11

Param