0

I have an array:

$arr = array(

    'Alcatel' => '0',
    'Apple' =>   '4542',
    'LG' =>      '0',
    'Nokia' =>   '0',
    'Samsung' => '2760',
    'Siemens' => '0',
    'Sony' =>    '0',

);

all the keys are alphabetically ordered, but the values are not. I want to: 1- maintain associations 2- sort the array by values HIGH to LOW 3- maintain alphabetical order for zero-value entries

to get:

$arr = array(

    'Apple' =>   '4542',
    'Samsung' => '2760',
    'Alcatel' => '0',
    'LG' =>      '0',
    'Nokia' =>   '0',
    'Siemens' => '0',
    'Sony' =>    '0',

);

now when I used arsort($arr);

I got:

$arr = array(
  'Apple' =>   '4542',
  'Samsung' => '2760',
  'Siemens' => '0',
  'Sony' =>    '0',
  'Nokia' =>   '0',
  'LG' =>      '0',
  'Alcatel' => '0',
);

So I got goals 1 and 2 and NOT 3

Any suggestion?

Thanks.

Anirudh Ramanathan
  • 46,179
  • 22
  • 132
  • 191
medk
  • 9,233
  • 18
  • 57
  • 79
  • 9
    [uasort](http://bg2.php.net/manual/en/function.uasort.php) and [uksort](http://bg2.php.net/manual/en/function.uksort.php) don't do the trick? – lanzz Nov 08 '12 at 22:31
  • 1
    This maybe be of some help to achieve #3 http://stackoverflow.com/questions/2282013/php-array-multiple-sort-by-value-then-by-key – Colin Swelin Nov 08 '12 at 22:32
  • 2
    Looking at the manual for uksort there seems to be several functions in the comments that does exactly this, and you did of course read the manual first. – adeneo Nov 08 '12 at 22:34
  • thanks for suggestions but may I have some code examples? – medk Nov 08 '12 at 22:40

2 Answers2

0

Ok, I finally did it:

Because $arr is a combination of 2 arrays, $titles and $values:

array_multisort($values, SORT_DESC, $titles, SORT_ASC, $arr);

this finally works!

medk
  • 9,233
  • 18
  • 57
  • 79
0

For the more general case, if you didn't have the keys and values already handy in separate source arrays, you would need a custom comparison function. There are versions of sort that pass the keys to the comparison function, and versions that pass the values, but you need both, and there isn't one that passes both in.

Since uksort passes the keys, you can look up the values, but if you access the array being sorted from the comparison function, you get unreliable results and a warning from PHP. So you need to make a copy.

The cleanest solution I could think of was to wrap the copy/access up in a closure (so this requires 5.4):

$arr = array(
    'Alcatel' => '0',
    'Apple' =>   '4542',
    'LG' =>      '0',
    'Nokia' =>   '0',
    'Samsung' => '2760',
    'Siemens' => '0',
    'Sony' =>    '0',
  );

  function mkcmp($arr) {
    return function($k1, $k2) use ($arr) {
      $v1 = $arr[$k1];
      $v2 = $arr[$k2];

      if ($v1 > $v2) {
        return -1;
      } else if ($v1 < $v2) {
        return 1;
      } else if ($k1 < $k2) {
        return -1;
      } else if ($k1 == $k2) {
        return 0;
      } else {
        return 1;
      }
    };
  }

  uksort($arr, mkcmp($arr));

And here's the output of print_r($arr) after the sort:

Array
(
    [Apple] => 4542
    [Samsung] => 2760
    [Alcatel] => 0
    [LG] => 0
    [Nokia] => 0
    [Siemens] => 0
    [Sony] => 0
)
Mark Reed
  • 91,912
  • 16
  • 138
  • 175