30

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.

2

4 Answers 4

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');
Sign up to request clarification or add additional context in comments.

5 Comments

If you are using PHP < 5.3.0, you'll need to move that anonymous function out of there.
you should not use PHP < 5.3.0 ;)
The uksort() example didn't work as I lost my array keys ('ABC','DEF','WW') but the array_multisort() did work -- thanks!
Shouldn't that be usort instead of uksort?
uksort sorts by Keys. Keys cannot be arrays and count does not count anything. usort compares values, which can be arrays.
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);
?>

1 Comment

If you use PHP 7, you can now just do count($a) <=> count($b); :)
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...

Comments

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);

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.