0

Possible Duplicate:
How do I sort a multidimensional array in php

........

This is not a duplicate. There are indeed tons of questions on stackoverflow regarding sorting multi-dimensional arrays (I believe I read most of them yesterday, before posting my question...), but none that I have seen refer to my particular problem: sorting by a varriying number of fields. The answer given by @dev-null-dweller below does just this.

........

I'm trying to create a flexible sort function for a multi-dimensional array in PHP.

The flexibility I'm after is for the number of sorting fields (could be 1, 2, or 3 for a 1st, 2nd or 3rd level sort), and for the identity of those fields.

This is a sample bit of my array:

Array
(
[0] => Array
    (
        [title] => Australia Book
        [price] => 209.00
        [code] => 3571313
        [con] => Australia & Oceania
        [ctry] => Australia
    )

[1] => Array
    (
        [title] => New Zealand Book
        [price] => 169.00
        [code] => 3571346
        [con] => Australia & Oceania
        [ctry] => New Zealand
    )

[2] => Array
    (
        [title] => Austria Book
        [price] => 129.00
        [code] => 3571230
        [con] => Europe
        [ctry] => Austria
    )

[3] => Array
    (
        [title] => Austria Pocket Book
        [price] => 119.00
        [code] => 3571354
        [con] => Europe
        [ctry] => Austria
    )



[4] => Array
    (
        [title] => Amsterdam Book
        [price] => 59.00
        [code] => 3571350
        [con] => Europe
        [ctry] => Netherlands
    )

[5] => Array
    (
        [title] => Britain
        [price] => 59.00
        [code] => 3571315
        [con] => Europe
        [ctry] => Britain
    )
)

I sometimes need to sort only by title, sometimes by ctry then title, sometimes by con, then ctry then title, etc.

I've managed to make a 2 level sort like so:

usort($arrCatalog, array('Catalogs_model', 'multi_compare'));

function multi_compare($a ,$b) {
if ($a['con'] < $b['con']) {
    return -1;
  } elseif  ($a['con'] > $b['con']) {
    return 1;
  } else {
    return strcmp($a['title'], $b['title']);
  }

}

The first question is how can I pass parameters to multi_compare function, when called from within usort.

After we settle that, I would be happy for some pointers as to how can I alter multi_sort so the identity and\or the number of fields will vary.

Community
  • 1
  • 1
einav
  • 553
  • 9
  • 25
  • You can pass prameters to an anonymous function: (using "use" keyword) http://php.net/manual/en/functions.anonymous.php – Muatik Dec 25 '12 at 09:51

1 Answers1

1

You are using static method for custom sorting, so you can set some static properties in this class before usort

class Catalogs_model{
    public static $usort_criteria = array();

    public static function multi_compare($a,$b){
        foreach(self::$usort_criteria as $what => $order){
            if($a[$what] == $b[$what]){
                continue;
            }
            return (($order == 'desc')?-1:1) * strcmp($a[$what], $b[$what]);
        }
        return 0;
    }
}

Catalogs_model::$usort_criteria = array(
   'con' => 'asc',
   'title' => 'asc'
);
usort($arrCatalog, array('Catalogs_model', 'multi_compare'));

of course it needs some tweaking , because now it only sorts strings.

dev-null-dweller
  • 28,330
  • 3
  • 60
  • 82