Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Flex: Sort -- Writing a custom compareFunction?

OK, I am sorting an XMLListCollection in alphabetical order. I have one issue though. If the value is "ALL" I want it to be first in the list. In most cases this happens already but values that are numbers are being sorted before "ALL". I want "ALL" to always be the first selection in my dataProvider and then the rest alphabetical.

So I am trying to write my own sort function. Is there a way I can check if one of the values is all, and if not tell it to do the regular compare on the values?

Here is what I have:

function myCompare(a:Object, b:Object, fields:Array = null):int
{
    if(String(a).toLowerCase() == 'all')
    {
        return -1;
    }
    else 
        if(String(b).toLowerCase() == 'all')
        {
            return 1;
        }
    // NEED to return default comparison results here?
}

//------------------------------

var sort:Sort = new Sort();
sort.compareFunction = myCompare;

Is there a solution for what I am trying to do?

like image 859
JD Isaacks Avatar asked Sep 02 '09 14:09

JD Isaacks


2 Answers

The solution from John Isaacks is awesome, but he forgot about "fields" variable and his example doesn't work for more complicated objects (other than Strings)

Example:

// collection with custom objects. We want to sort them on "value" property
// var item:CustomObject = new CustomObject();
// item.name = 'Test';
// item.value = 'Simple Value';

var collection:ArrayCollection = new ArrayCollection();
var s:Sort = new Sort();
s.fields = [new SortField("value")];
s.compareFunction = myCompare;
collection.sort = s;
collection.refresh();

private function myCompare(a:Object, b:Object, fields:Array = null):int
{
    if(String((a as CustomObject).value).toLowerCase() == 'all')
    {
        return -1;
    }
    else if(String((b as CustomObject).value).toLowerCase() == 'all')
    {
        return 1;
    }
    // NEED to return default comparison results here?
    var s:Sort = new Sort();
    s.fields = fields;
    var f:Function = s.compareFunction;
    return f.call(null,a,b,fields);
}
like image 86
Jarek Szczepański Avatar answered Nov 15 '22 09:11

Jarek Szczepański


Well I tried something out, and I am really surprised it actually worked, but here is what I did.

The Sort class has a private function called internalCompare. Since it is private you cannot call it. BUT there is a getter function called compareFunction, and if no compare function is defined it returns a reference to the internalCompare function. So what I did was get this reference and then call it.

private function myCompare(a:Object, b:Object, fields:Array = null):int
{
    if(String(a).toLowerCase() == 'all')
    {
        return -1;
    }
    else if(String(b).toLowerCase() == 'all')
    {
        return 1;
    }
    // NEED to return default comparison results here?
    var s:Sort = new Sort();
    var f:Function = s.compareFunction;
    return f.call(null,a,b,fields);
}
like image 37
JD Isaacks Avatar answered Nov 15 '22 08:11

JD Isaacks