0

Hi i am facing problem in sorting multidimensional array by different key,such as by date, by category, by weight in any specific order.

I can not order these array by mysql order by feature as i have to implement a tough business logic on mysql output array (data)..

After implementing business logic i found following type of array that need to be sorted by

date asc,category desc,weight asc.

array have size of 10000 or more.

i have already used usort function but it can't resolve issue of fixed ordering in case of same value of sorting elements.

plz help.

Array
(
    [0] => Array
        (
            [categorie] => xyz
            [date] => 2012-12-08 19:30
            [weight] => 3
            [row_id] => 125812
            [searchtype] => show
            [uitgespeeld] => 0
        )

[1] => Array
    (
        [categorie] => show
        [date] => 2012-12-10 20:15
        [weight] => 3
        [row_id] => 125816
        [searchtype] => show
        [uitgespeeld] => 0
    )

[2] => Array
    (
        [categorie] => abc
        [date] => 2012-12-13 20:30
        [weight] => 3
        [row_id] => 119151
        [searchtype] => show
        [uitgespeeld] => 0
    )
   .......

)

Code i have used for sorting.

usort($temp_group_data, array('className','cmp_weight'));
usort($temp_group_data, array('className','cmp_date'));

function cmp_weight($a, $b) {
    if (($a['weight']==$b['weight']) ) {
        return 0;
    } else if ($a['weight'] >$b['weight']) {
        return -1;
    } else {
        return 1;
    }
}

function cmp_date($a, $b) {
    if (($a['date']==$b['date']) ) {
        return 0;
    } else if (strtotime($a['date']) >strtotime($b['date'])) {
        return -1;
    } else {
        return 1;
    }
}
Alexander Yancharuk
  • 13,817
  • 5
  • 55
  • 55
praveen
  • 194
  • 1
  • 10

2 Answers2

2

You have to do it in one function, now second sorting overwrites changes made in first.

function multicompare($a,$b){
    $criteria = array(
        'date' => 'asc',
        'category' => 'desc',
        'weight' => 'asc'
    );
    foreach($criteria as $what => $order){
        if($a[$what] == $b[$what]){
            continue;
        }
        return (($order == 'desc')?-1:1) * strcmp($a[$what], $b[$what]);
    }
    return 0;
}
dev-null-dweller
  • 29,274
  • 3
  • 65
  • 85
  • Thanks for your help.I need sorting by date,category and weight by using one function. does your function work in that case? – praveen Dec 02 '12 at 20:42
  • 1
    It is example that illustrates idea of handling many criteria in one function. Don't treat is as a final working product, it is your job to do one. – dev-null-dweller Dec 02 '12 at 21:13
0

The problem is two-fold, judging by the last part of your question:

  1. All conditions must be evaluated at the same time rather than consecutively.

  2. You need stable sorting to retain the ordering in case two values are the same (i.e. the original order)

Both steps in one goes like this; first you "decorate" the array using the index in which they appear in the original array:

foreach ($a as $key => &$item) {
    $item = array($item, $key); // add array index as secondary sort key
}

usort($a, 'mysort'); // sort it

// undecorate
foreach ($a as $key => &$item) {
    $item = $item[0]; // remove decoration from previous step
}

And here's the all-in-one sorting function:

function mysort($a, $b)
{
    if ($a[0]['date'] != $b[0]['date']) {
            return $a[0]['date'] < $b[0]['date'] ? -1 : 1; // ASC
    } elseif ($a[0]['category'] != $b[0]['category']) {
            return $a[0]['category'] < $b[0]['category'] ? 1 : -1; // DESC
    } elseif ($a[0]['weight'] != $b[0]['weight']) {
            return $a[0]['weight'] < $b[0]['weight'] ? -1 : 1; // ASC
    } else {
            return $a[1] < $b[1] ? -1 : 1; // ASC
    }
}
Ja͢ck
  • 170,779
  • 38
  • 263
  • 309