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;

0

4 Answers 4

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

Comments

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

5 Comments

I know about usort() just cannot figure out how to use it in this particular case.
Remember that you retrieve arrays if you use usort in a multidimensional context. It's a hard concept to grip and visualise. The usort() manual has some great examples.
@redacted, the example above takes an array in the format you've given an sorts it according to player id.
This works per single column but when i sort by 2 column it does not work please check my original question for details.
Never mind it was just using return 0; excecuted before second if. Is using return 0; increase speed or smth?
0

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

2 Comments

I know about usort() just cannot figure out how to use it in this particular case.
nyson already started the solution for you. Just add more if...else loops.
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);

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.