29

I have an array such as:

$array = [
    'DEF' => [
        ['type' => 1, 'id' => 1212, 'name' => 'Jane Doe', 'current' => 1],
        ['type' => 1, 'id' => 3123121, 'name' => 'Door', 'current' => null],
    ],
    'ABC' => [
        ['type' => 1, 'id' => 1234, 'name' => 'John Doe', 'current' => null],
    ],
    'WW' => [
        ['type' => 1, 'id' => 1212, 'name' => 'Jane Doe', 'current' => 1],
        ['type' => 1, 'id' => 3123121, 'name' => 'Door', 'current' => null],
        ['type' => 1, 'id' => 64646, 'name' => 'Floor', 'current' => null],
    ]
];

And I want to sort this array by number ( count() ) of inner-array items descending (i.e. most items first), so I will have this array:

[
    'WW' => [
        ['type' => 1, 'id' => 1212, 'name' => 'Jane Doe', 'current' => 1],
        ['type' => 1, 'id' => 3123121, 'name' => 'Door', 'current' => null],
        ['type' => 1, 'id' => 64646, 'name' => 'Floor', 'current' => null],
    ],
    'DEF' => [
        ['type' => 1, 'id' => 1212, 'name' => 'Jane Doe', 'current' => 1],
        ['type' => 1, 'id' => 3123121, 'name' => 'Door', 'current' => null],
    ],
    'ABC' => [
        ['type' => 1, 'id' => 1234, 'name' => 'John Doe', 'current' => null],
    ]
];

Can anyone suggest an efficient way to do so? Thanks.

mickmackusa
  • 43,625
  • 12
  • 83
  • 136
Aviram
  • 3,017
  • 4
  • 29
  • 43

4 Answers4

40

Using uksort:

uksort($array, function($a, $b) { return count($b) - count($a); });

Using array_multisort:

array_multisort(array_map('count', $array), SORT_DESC, $array);

With PHP < 5.3:

function sort_cb($a, $b) {
    return count($b) - count($a);
}
uksort($array, 'sort_cb');
Arnaud Le Blanc
  • 98,321
  • 23
  • 206
  • 194
4
<?php
function cmp($a, $b)
{
    if ($a == $b) {
        return 0;
    }
    return (count($a) > count($b)) ? -1 : 1;
}

$a = array(
"AA" => array(
        array('type'=>'1', 'id'=>'2'),
        array('type'=>'2', 'id'=>'2')),
'BB' => array(
        array('type'=>'1', 'id'=>'2'),
        array('type'=>'2', 'id'=>'2'),
        array('type'=>'5', 'id'=>'2')),
'CC' => array(
        array('type'=>'1', 'id'=>'2'))
);  

usort($a, "cmp");

print_r($a);
?>
Dan Bizdadea
  • 1,292
  • 8
  • 15
1
$tempArr = $sortedArr = array();
foreach ($myArr as $k => $v) $tempArr[$k] = count($v);
asort($tempArr);
foreach ($tempArr as $k => $v) $sortedArr = $myArr[$k];

Note that this will break if any of the array values are not themselves arrays, you may want to add an is_array() check somewhere...

DaveRandom
  • 87,921
  • 11
  • 154
  • 174
0

If you are only worried about sorting on size and not the actual quality, you can use the simplest approach to sort descending and preserve keys with arsort().

Array with fewer members is smaller, if key from operand 1 is not found in operand 2 then arrays are incomparable, otherwise - compare value by value (see following example)

In the event that you have multiple rows with the same size, then they will be further sorted descending based on their actual data.

Code: (Demo)

arsort($array);
var_export($array);
mickmackusa
  • 43,625
  • 12
  • 83
  • 136