0
$arr=array(
    [0]=>array(
        [username]=>bsmith
        [name]=>Bob Smith
    )
    [1]=>array(
        [username]=>mjohnson
        [name]=>Mike Johnson
    )
    [2]=>array(
        [username]=>ameyer
        [name]=>Meyer Adam
    )
)

Need to natural (alphabetical) sort by a specific sub-value of the array.

If sort by "username" => => ameyer, bsmith, mjohnson

$arr=array(
    [0]=>array(
        [username]=>ameyer
        [name]=>Meyer Adam
    )
    [1]=>array(
        [username]=>bsmith
        [name]=>Bob Smith
    )
    [2]=>array(
        [username]=>mjohnson
        [name]=>Mike Johnson
    )

)

If sort by "name" => bsmith, ameyer, mjohnson

$arr=array(
    [0]=>array(
        [username]=>bsmith
        [name]=>Bob Smith
    )
    [1]=>array(
        [username]=>ameyer
        [name]=>Meyer Adam
    )
    [2]=>array(
        [username]=>mjohnson
        [name]=>Mike Johnson
    )
)

What is the most elegant way to do that?

Should I use uasort?

ihtus
  • 2,673
  • 13
  • 40
  • 58
  • possible duplicate of [How do I sort a multidimensional array in php](http://stackoverflow.com/questions/96759/how-do-i-sort-a-multidimensional-array-in-php) – Ryan Jul 24 '13 at 18:36

3 Answers3

2

You will need to use usort, which will both be the easiest and fastest method. You can just use the result code of strcmp to determine the alpha sort order.

function sortByUsername($a, $b) {
  return strcmp($a['username'], $b['username']);
}

usort($arr, sortByUsername);
Geoffrey
  • 10,843
  • 3
  • 33
  • 46
  • how uasort is working? what is $a and $b in this particular case? – ihtus Jul 24 '13 at 18:43
  • `uasort` calls `sortByUsername` with the two elements to compare. That said, I much prefer JimiDini's solution, it is much more flexable. – Geoffrey Jul 24 '13 at 18:44
  • there is no need to use uasort. usort is enough, as the top-level array is not associative. Also see my answer for generic solution – JimiDini Jul 24 '13 at 18:46
  • @ihtus php engine will send pairs of various elements from your array there until it gets enough eveidence of how sorted array should look like – JimiDini Jul 24 '13 at 18:47
  • so first time it sends pairs 0 and 1; then 1 ad 2? – ihtus Jul 24 '13 at 18:49
  • @ihtus something like that, yes. you can do experiment by adding logger to the sorter function :) – JimiDini Jul 24 '13 at 18:51
  • @ihtus there's an elegant practical answer below. if you're interested in theoretical part of this, take a look here: http://stackoverflow.com/questions/12208364/understanding-array-sorting-or-comparison-function-callbacks-using-user-defined?lq=1 – JimiDini Jul 24 '13 at 18:57
  • guys, how alphabetical sort is achieved using strcmp by comparing which string is longer or shorter? – ihtus Jul 24 '13 at 19:15
  • `strcmp` does not compare string length. – Geoffrey Jul 24 '13 at 19:15
  • manual: Returns < 0 if str1 is less than str2; > 0 if str1 is greater than str2, and 0 if they are equal. – ihtus Jul 24 '13 at 19:16
  • @ihtus "less" doesn't mean shorter :) it does lexicographic comparision. see https://en.wikipedia.org/wiki/Lexicographical_order – JimiDini Jul 24 '13 at 19:16
  • less then = less then alphabetically, not length. ie: 'a' is less then 'b'. – Geoffrey Jul 24 '13 at 19:17
  • http://www.tuxradar.com/practicalphp/4/7/15 It takes two words for its two parameters, and returns -1 if word one comes alphabetically before word two, 1 if word one comes alphabetically after word two, or 0 if word one and word two are the same. – ihtus Jul 24 '13 at 19:19
  • We know this.. why post it here? – Geoffrey Jul 24 '13 at 19:23
  • for anyone who does not know, like me :) – ihtus Jul 24 '13 at 19:23
2
$sorter = function($key) {
    return function($data, $data2) use ($key) {
        return strcmp($data[$key], $data2[$key]);
    };
};

usort($arr, $sorter('username'));
var_dump($arr);

usort($arr, $sorter('name'));
var_dump($arr);
JimiDini
  • 2,039
  • 12
  • 19
0

You can use array_multisort:

foreach ($arr as $array) {
    $names[] = $array['name'];
}

array_multisort($names,SORT_STRING,$arr);
print_r($arr);
jh314
  • 27,144
  • 16
  • 62
  • 82