5

I have an array looking like this:

Array(
   ['some_first_category'] => Array(
            ['some_first_name'] => Array(
                           [0]=>'first@email.com',
                           [1]=>'second@email.com',
                           [2]=>'third@email.com',
                           [3]=>'fourth@email.com' )
             ['some_second_name'] => Array (
                           [1]=>'first@email.com',
                           [2]=>'second@email.com')
             ['some_third_name'] => Array(
                           [1]=>'first@email.com',
                           [2]=>'second@email.com',
                           [3]=>'third@email.com',
                           [4]=>'fourth@email.com' )
   ['some_second_category'] => Array(
            ['some_first_name'] => Array(
                           [0]=>'first@email.com' )
             ['some_second_name'] => Array(
                           [1]=>'first@email.com',
                           [2]=>'second@email.com',
                           [3]=>'third@email.com',
                           [4]=>'fourth@email.com')
             ['some_third_name'] => Array(
                           [1]=>'first@email.com',
                           [2]=>'second@email.com'))

And I want to sort the array by the number of values of that has the names, In my case I want to become this array:

Array(
   ['some_first_category'] => Array(
             ['some_third_name'] => Array(
                           [1]=>'first@email.com',
                           [2]=>'second@email.com',
                           [3]=>'third@email.com',
                           [4]=>'fourth@email.com' )
            ['some_first_name'] => Array(
                           [0]=>'first@email.com',
                           [1]=>'second@email.com',
                           [2]=>'third@email.com',
                           [3]=>'fourth@email.com' )
             ['some_second_name'] => Array (
                           [1]=>'first@email.com',
                           [2]=>'second@email.com')

   ['some_second_category'] => Array(
             ['some_second_name'] => Array(
                           [1]=>'first@email.com',
                           [2]=>'second@email.com',
                           [3]=>'third@email.com',
                           [4]=>'fourth@email.com')
             ['some_third_name'] => Array(
                           [1]=>'first@email.com',
                           [2]=>'second@email.com')
            ['some_first_name'] => Array(
                           [0]=>'first@email.com' ))

This means sorting categories by name by the number(count) of values of the names. Someone can help me? Thanks in advance,

Aäron

Ari
  • 934
  • 1
  • 10
  • 15
  • I see that you want to sort the second level ("name") by number of child elements descending, but do you also want to sort the first level ("category") by some logic? – Passerby Feb 05 '13 at 10:01
  • It isn't sorted. It's just a display specific to your needs. – hjpotter92 Feb 05 '13 at 10:02
  • I want also some one to wash my car! but if I washed and I failed, its ok to ask a friend to help me! –  Feb 05 '13 at 10:03
  • ppl should learn that this side is supposed to give support, not full solutions to questions. You and only you have to do the work, if you need help that's ok, but asking for the solution w/o trying anything it's just cheap. – Naryl Feb 05 '13 at 10:06

3 Answers3

17

All you need is uasort

uasort($list, function ($a, $b) {
    $a = count($a);
    $b = count($b);
    return ($a == $b) ? 0 : (($a < $b) ? -1 : 1);
});

Full Example

$list = Array(
   'some_first_category' => Array(
            'some_first_name' => Array(
                           0=>'first@email.com',
                           1=>'second@email.com',
                           2=>'third@email.com',
                           3=>'fourth@email.com' ),
             'some_second_name' => Array (
                           1=>'first@email.com',
                           2=>'second@email.com'),
             'some_third_name' => Array(
                           1=>'first@email.com',
                           2=>'second@email.com',
                           3=>'third@email.com',
                           4=>'fourth@email.com' )
        ),
   'some_second_category' => Array(
            'some_first_name' => Array(
                           0=>'first@email.com' ),
             'some_second_name' => Array(
                           1=>'first@email.com',
                           2=>'second@email.com',
                           3=>'third@email.com',
                           4=>'fourth@email.com'),
             'some_third_name' => Array(
                           1=>'first@email.com',
                           2=>'second@email.com'))

    );

$list = array_map(function ($v) {
    uasort($v, function ($a, $b) {
        $a = count($a);
        $b = count($b);
        return ($a == $b) ? 0 : (($a < $b) ? 1 : - 1);
    });
    return $v;
}, $list);


print_r($list);

Output

Array
(
    [some_first_category] => Array
        (
            [some_first_name] => Array
                (
                    [0] => first@email.com
                    [1] => second@email.com
                    [2] => third@email.com
                    [3] => fourth@email.com
                )

            [some_third_name] => Array
                (
                    [1] => first@email.com
                    [2] => second@email.com
                    [3] => third@email.com
                    [4] => fourth@email.com
                )

            [some_second_name] => Array
                (
                    [1] => first@email.com
                    [2] => second@email.com
                )

        )

    [some_second_category] => Array
        (
            [some_second_name] => Array
                (
                    [1] => first@email.com
                    [2] => second@email.com
                    [3] => third@email.com
                    [4] => fourth@email.com
                )

            [some_third_name] => Array
                (
                    [1] => first@email.com
                    [2] => second@email.com
                )

            [some_first_name] => Array
                (
                    [0] => first@email.com
                )

        )

)
Baba
  • 94,024
  • 28
  • 166
  • 217
  • dont put functions in parameters of functions. this is not jQuery :P – dognose Feb 05 '13 at 10:09
  • 2
    @dognose So you'd rather pointlessly assign the closure to a variable or clutter the global namespace with a function identifier then? The only reason to avoid inline closures is if you need to support <=5.2, if you need to do that you need a better job and/or host. – DaveRandom Feb 05 '13 at 10:17
  • Thanks a lot Baba !! The usort function I already tried it myself but it doesn't maintain the key of the array's. Thanks for the help everybody! – Ari Feb 05 '13 at 10:21
  • @DaveRandom A Sort function is not related to the context imho. So I might reuse it, so yes, I would put it somewhere global because then I don't need to rewrite or copy/paste it. – dognose Feb 05 '13 at 10:40
5

Using uksort:

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

Using array_multisort:

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

and you can see uasort as well

best of luck :)

manish1706
  • 1,571
  • 24
  • 22
  • 1
    Perfect thanks... array_multisort(array_map('count', $yourArray), SORT_DESC, $yourArray); this worked for me – Abhishek Goel Nov 30 '16 at 14:13
  • `uasort($yourArray, function($a, $b) { return count($b) - count($a); });` worked great for me. if you want to reverse the sort order you can swap $a and $b in the count functions. – murtho Apr 13 '19 at 13:16
1

You should use usort function. Refer here.

function sort_sub($a,$b)
{
$res= count($b)-count($a);
return $res;
}

usort($array_name,'sort_sub')
Community
  • 1
  • 1
Vishnu R
  • 1,859
  • 3
  • 26
  • 45