0

I have a table/array. E.g. in Excel I can sort by column 1 asc, column 2 desc, column 3 asc, etc.

Can I do same in PHP? First with ["first_name"] ASC, then ["last_name"] DESC, ["player_id"] ASC and ["user_id"] DESC.

array(2) {
    [0]=> array(6) {
        [0]=> string(8) "John",
        ["first_name"]=> string(8) "John",
        [1]=> int(7) "44",
        ["score"]=> int(7) "44",
        [2]=> string(2) "7",
        ["player_id"]=> string(2) "7",
        [3]=> string(2) "3",
        ["user_id"]=> string(2) "3"
    },
    [1]=> array(6) {
        [0]=> string(5) "Sam",
        ["first_name"]=> string(5) "Sam",
        [1]=> int(7) "55",
        ["score"]=> int(7) "55",
        [2]=> string(2) "1",
        ["player_id"]=> string(2) "1",
        [3]=> string(2) "6",
        ["user_id"]=> string(2) "61"
    }
}

(The array is much longer and deeper in reality, this is just an example.)

Update:

function byPlayerID($player, $compare) {
    if($player['player_id'] > $compare['player_id'])
        return 1; // move up
    else if($player['player_id'] < $compare['player_id'])
        return -1; // move down
    else
        return 0; // do nothing

    if($player['score'] > $compare['score'])
        return 1; // move up
    else if($player['score'] < $compare['score'])
        return -1; // move down
    else
        return 0; // do nothing
}

Update 2: Never mind, I just needed to remove return 0;

Bas Peeters
  • 3,269
  • 4
  • 33
  • 49
redacted
  • 453
  • 1
  • 5
  • 7

4 Answers4

5

array_multisort is the function you are looking for.

And here is an example function written using array_multisort

https://gist.github.com/1220785

using

   $sorted_arraty = sort_array_multidim($array,"first_name ASC, last_name DESC, player_id ASC, user_id DESC");
1

Use usort().

Example:

$byPlayerID = function($player, $compare) {
  if($player['player_id'] > $compare['player_id'])
    return 1; // move up
  else if($player['player_id'] < $compare['player_id'])
    return -1; // move down
  else
    return 0; // do nothing
};

usort($players, $byPlayerID);
// now $players is sorted!

This does require PHP 5.3 though, below is a more backwards compatible version

function byPlayerID($player, $compare) {
  if($player['player_id'] > $compare['player_id'])
    return 1; // move up
  else if($player['player_id'] < $compare['player_id'])
    return -1; // move down
  else
    return 0; // do nothing
}

usort($players, "byPlayerID");
nyson
  • 1,055
  • 6
  • 20
  • I know about usort() just cannot figure out how to use it in this particular case. – redacted Jun 01 '12 at 07:42
  • Remember that you retrieve arrays if you use usort in a multidimensional context. It's a hard concept to grip and visualise. The [usort](http://se.php.net/manual/en/function.usort.php)() manual has some great examples. – nyson Jun 01 '12 at 07:47
  • @redacted, the example above takes an array in the format you've given an sorts it according to player id. – nyson Jun 01 '12 at 08:19
  • This works per single column but when i sort by 2 column it does not work please check my original question for details. – redacted Jun 03 '12 at 19:12
  • Never mind it was just using return 0; excecuted before second if. Is using return 0; increase speed or smth? – redacted Jun 03 '12 at 19:41
0

Use the PHP function usort to compare values as you need. Extend your callback function to compare multiple values.

Paul
  • 8,974
  • 3
  • 28
  • 48
0

For those who find this in the future, here's a final working version that fully answers the original question. This sorts by four different key values.

$byPlayerID = function($a, $b) {

  // Sort by first
  // > to return 1, < to return -1 = ASC order
  if($a['first_name'] > $b['first_name']) return 1; // move up
  else if($a['first_name'] < $b['first_name']) return -1; // move down

  // Sort by second
  // < to return 1, > to return -1 = DESC order
  if($a['last_name'] < $b['last_name']) return 1; // move up
  else if($a['last_name'] > $b['last_name']) return -1; // move down

  // Sort by third
  // > to return 1, < to return -1 = ASC order
  if($a['player_id'] > $b['player_id']) return 1; // move up
  else if($a['player_id'] < $b['player_id']) return -1; // move down

  // Sort by fourth
  // < to return 1, > to return -1 = DESC order
  if($a['user_id'] < $b['user_id']) return 1; // move up
  else if($a['user_id'] > $b['user_id']) return -1; // move down

  else return 0; // do nothing

};

usort($stats, $byPlayerID);
Jeremy Caris
  • 117
  • 1
  • 8