5

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?

Community
  • 1
  • 1
Simone
  • 185
  • 1
  • 2
  • 8
  • 1
    Apropos "The Problem", although sortParameter isn't passed to the compare function, but the compare function has access to sortParameter because of 'closure'. You just need to change a.sortParameter to a[sortParameter]. – Param Oct 21 '13 at 06:58

1 Answers1

3

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].

Param
  • 2,420
  • 1
  • 14
  • 10
  • Well, that apparently worked for me! What I still don't understand is the reason why we changed `a.sortParameter` to `a[sortParameter]`. Is there any logical reason for that? Are there any documentations regarding this issue? – Simone Oct 21 '13 at 07:08
  • I believe that by calling `a.sortParameter`, sortParameter is considered to be treated as an actual key of the object rather than a passed parameter. Am I right? – Simone Oct 21 '13 at 07:10
  • 1
    If you use a.xxx then xxx is interpreted statically. So, your second comment above is right. Also, I've modified the code to account for conversion of strings to numbers before comparison (if appropriate). E.g. "7" > "20" but 7 < 20 – Param Oct 21 '13 at 07:14