May 15, 2008

Extjs.util.MixedCollection : how to sort ?

  1. Introduction
  2. Look at the code
  3. Example: generic sort
This arcticle studies Extjs in 2.0.2 version.

I recently had to use Ext that is by the way a wonderfull library, no matter the licencing issues that occured lately. Ext.util.MixedCollection is a class allowing to store any type of data and to add, remove, filter and sort it.

Adding or removing data is quite easy, you just have to read the documentation, to filter, just give the field you want to filter and the pattern you want to match, but when it comes to sort, the documentation isn't really helpfull.

We'll first have a look to the code and then we'll give a simple sort example.

Table of content

Let's find the sort method :

    sort : function(dir, fn){
        this._sort("value", dir, fn);
    }

As we can see, it is really short, it just calls a private function named _sort. Let's go deeper into the layers and study the _sort method ;)

    _sort : function(property, dir, fn){
        var dsc = String(dir).toUpperCase() == "DESC" ? -1 : 1;
        fn = fn || function(a, b){
            return a-b;
        };
        var c = [], k = this.keys, items = this.items;
        for(var i = 0, len = items.length; i < len; i++){
            c[c.length] = {key: k[i], value: items[i], index: i};
        }
        c.sort(function(a, b){
            var v = fn(a[property], b[property]) * dsc;
            if(v == 0){
                v = (a.index < b.index ? -1 : 1);
            }
            return v;
        });
        for(var i = 0, len = c.length; i < len; i++){
            items[i] = c[i].value;
            k[i] = c[i].key;
        }
        this.fireEvent("sort", this);
    }

As we can see, the default sort callback is defined as follows : return a - b ;, and then this callback is passed to the array sorter. So, the function format is the same as for the Array.prototype.sort function.

Table of content

Let's define the environement (I will not include a test directly in the blog because of Extjs weight):

//creation
var characters = new OWT.util.MixedCollection();
//populate
characters.addAll([
   {id: 1, first_name: 'Kyle', last_name: 'Broflovski', age: '8', phone: '555-14569'},
   {id: 2, first_name: 'Eric', last_name: 'Cartman', age: '8', phone: '555-96541'},
   {id: 3, first_name: 'Stanley', last_name: 'March', age: '8', phone: '555-12478'},
   {id: 4, first_name: 'Kenny', last_name: 'McCormick', age: '8', phone: '555-78954'},
   {id: 5, first_name: 'Leopold', last_name: 'Stotch', age: '8', phone: '555-63215'},
   {id: 6, first_name: 'Jesus', last_name: 'Christ', age: '2008', phone: '555-12479'}
  ]);

If you want to sort this collection easyly, just use following function:

function sort_characters( asFieldName, asOrder)
{
    var _sFieldName = asFieldName, 
        _fSorter = function(obj1, obj2){
            if( isFinite( obj1[sFieldName] - obj2[sFieldName] ) )
                return  obj1[sFieldName] - obj2[sFieldName] ;
            return obj1[asFieldName] > obj2[asFieldName] ? 1:-1
        }
    characters.sort(asOrder || 'DESC', _fSorter);
}

Here we are !
See you soon

Table of content

1 comment:

Unknown said...

Can anybody please let me know how to write generic function to sort mixed arrays in javascript & also generic function to sort primitive.