php array_multisort sorting columns i didnt ask to be sorted

php sort multidimensional array by column
php sort multidimensional array by value descending
php sort multidimensional array by specific key value
php sort multidimensional array by value alphabetically
php sort array by column
php sort multidimensional array by date
usort ascending php
php sort multidimensional array by key descending

i am sorting a multidimensional array by one of the columns using array_multisort. yes, i know this function is not needed to sort by only one column, but this is for code where there could be more columns being sorted on and right now only the one test is failing.

when i run a test i found on the interwebs, it works fine. when i run pretty much the exact same thing with some other test data, it is ALSO sorting on a column i didnt ask it to sort on.

This test returns proper sorted data (value NOT sorted):

$vc_array = array (
0 => array ('id' => 1,'name' => 'xyz','value' => 'abc','order' => 6),
 1 => array ('id' => 2,'name' => 'abc','value' => 'xyz','order' => 2),
 2 => array ('id' => 3,'name' => 'uvw','value' => 'ghi','order' => 1),
 3 => array ('id' => 4,'name' => 'def','value' => 'xyz','order' => 2,),
 4 => array ('id' => 5,'name' => 'ghi','value' => 'uvw','order' => 3),
 5 => array ('id' => 6,'name' => 'ghi','value' => 'def','order' => 3),
 6 => array ('id' => 7,'name' => 'ghi','value' => 'fff','order' => 3)
);

$vc_array_name = array_column($vc_array, 'name');

$out = array_multisort($vc_array_name, SORT_ASC, $vc_array);

var_dump($vc_array); // note the name 'ghi' and the order of the 'value' column.  the 'value' column has NOT been sorted, which is what is expected.

Dumped data:

array(7) { [0]=> array(4) { ["id"]=> int(2) ["name"]=> string(3) "abc" ["value"]=> string(3) "xyz" ["order"]=> int(2) } [1]=> array(4) { ["id"]=> int(4) ["name"]=> string(3) "def" ["value"]=> string(3) "xyz" ["order"]=> int(2) } [2]=> array(4) { ["id"]=> int(5) ["name"]=> string(3) "ghi" ["value"]=> string(3) "uvw" ["order"]=> int(3) } [3]=> array(4) { ["id"]=> int(6) ["name"]=> string(3) "ghi" ["value"]=> string(3) "def" ["order"]=> int(3) } [4]=> array(4) { ["id"]=> int(7) ["name"]=> string(3) "ghi" ["value"]=> string(3) "fff" ["order"]=> int(3) } [5]=> array(4) { ["id"]=> int(3) ["name"]=> string(3) "uvw" ["value"]=> string(3) "ghi" ["order"]=> int(1) } [6]=> array(4) { ["id"]=> int(1) ["name"]=> string(3) "xyz" ["value"]=> string(3) "abc" ["order"]=> int(6) } }

This test sorts properly on the 'name' field, but is also sorting on the 'quantity' field which i did NOT request, and do not want that column to be sorted:

$objectListData4 =  [
        ["name" => "package", "quantity" => 1000, "color" => "brown"],
        ["name" => "box", "quantity" => 1000, "color" => "red"],
        ["name" => "notebook", "quantity" => 250, "color" => "orange"],
        ["name" => "pencil", "quantity" => 100, "color" => "yellow"],
        ["name" => "bag", "quantity" => 150, "color" => "blue"],
        ["name" => "box", "quantity" => 1200, "color" => "pink"],
        ["name" => "notebook", "quantity" => 50, "color" => "blue"],
        ["name" => "package", "quantity" => 1500, "color" => "green"],
        ["name" => "bag", "quantity" => 500, "color" => "green"],
        ["name" => "notebook", "quantity" => 100, "color" => "yellow"],
    ];

$tmp = array_column($objectListData4, 'name');
array_multisort($tmp, SORT_ASC, $objectListData4);

var_dump($objectListData4); // note the name 'notebook' and the order of the 'quantity' column.  the 'quantity' column has also been sorted but shouldnt be

Dumped data:

array(10) { [0]=> array(3) { ["name"]=> string(3) "bag" ["quantity"]=> int(150) ["color"]=> string(4) "blue" } [1]=> array(3) { ["name"]=> string(3) "bag" ["quantity"]=> int(500) ["color"]=> string(5) "green" } [2]=> array(3) { ["name"]=> string(3) "box" ["quantity"]=> int(1000) ["color"]=> string(3) "red" } [3]=> array(3) { ["name"]=> string(3) "box" ["quantity"]=> int(1200) ["color"]=> string(4) "pink" } [4]=> array(3) { ["name"]=> string(8) "notebook" ["quantity"]=> int(50) ["color"]=> string(4) "blue" } [5]=> array(3) { ["name"]=> string(8) "notebook" ["quantity"]=> int(100) ["color"]=> string(6) "yellow" } [6]=> array(3) { ["name"]=> string(8) "notebook" ["quantity"]=> int(250) ["color"]=> string(6) "orange" } [7]=> array(3) { ["name"]=> string(7) "package" ["quantity"]=> int(1000) ["color"]=> string(5) "brown" } [8]=> array(3) { ["name"]=> string(7) "package" ["quantity"]=> int(1500) ["color"]=> string(5) "green" } [9]=> array(3) { ["name"]=> string(6) "pencil" ["quantity"]=> int(100) ["color"]=> string(6) "yellow" } }

Can anyone see why the second test is also sorting the quantity when it shouldnt be??

I'm not sure what the cause for your error is, I suspect it's undocumented functionality that array_multisort sorts arrays of arrays by looking for the next available associative key or something.

But a solution to make sure no further sorting will take place is to pass in the array keys as the 2nd sort parameter. Working version of your second given example:

$objectListData4 =  [
        ["name" => "package", "quantity" => 1000, "color" => "brown"],
        ["name" => "box", "quantity" => 1000, "color" => "red"],
        ["name" => "notebook", "quantity" => 250, "color" => "orange"],
        ["name" => "pencil", "quantity" => 100, "color" => "yellow"],
        ["name" => "bag", "quantity" => 150, "color" => "blue"],
        ["name" => "box", "quantity" => 1200, "color" => "pink"],
        ["name" => "notebook", "quantity" => 50, "color" => "blue"],
        ["name" => "package", "quantity" => 1500, "color" => "green"],
        ["name" => "bag", "quantity" => 500, "color" => "green"],
        ["name" => "notebook", "quantity" => 100, "color" => "yellow"],
    ];

$tmp = array_column($objectListData4, 'name');
array_multisort($tmp, SORT_ASC, array_keys($objectListData4), $objectListData4);

var_dump($objectListData4); // note the name 'notebook' and the order of the 'quantity' column.  the 'quantity' column has also been sorted but shouldnt be

And it's output:

array(10) {
  [0]=>
  array(3) {
    ["name"]=>
    string(3) "bag"
    ["quantity"]=>
    int(150)
    ["color"]=>
    string(4) "blue"
  }
  [1]=>
  array(3) {
    ["name"]=>
    string(3) "bag"
    ["quantity"]=>
    int(500)
    ["color"]=>
    string(5) "green"
  }
  [2]=>
  array(3) {
    ["name"]=>
    string(3) "box"
    ["quantity"]=>
    int(1000)
    ["color"]=>
    string(3) "red"
  }
  [3]=>
  array(3) {
    ["name"]=>
    string(3) "box"
    ["quantity"]=>
    int(1200)
    ["color"]=>
    string(4) "pink"
  }
  [4]=>
  array(3) {
    ["name"]=>
    string(8) "notebook"
    ["quantity"]=>
    int(250)
    ["color"]=>
    string(6) "orange"
  }
  [5]=>
  array(3) {
    ["name"]=>
    string(8) "notebook"
    ["quantity"]=>
    int(50)
    ["color"]=>
    string(4) "blue"
  }
  [6]=>
  array(3) {
    ["name"]=>
    string(8) "notebook"
    ["quantity"]=>
    int(100)
    ["color"]=>
    string(6) "yellow"
  }
  [7]=>
  array(3) {
    ["name"]=>
    string(7) "package"
    ["quantity"]=>
    int(1000)
    ["color"]=>
    string(5) "brown"
  }
  [8]=>
  array(3) {
    ["name"]=>
    string(7) "package"
    ["quantity"]=>
    int(1500)
    ["color"]=>
    string(5) "green"
  }
  [9]=>
  array(3) {
    ["name"]=>
    string(6) "pencil"
    ["quantity"]=>
    int(100)
    ["color"]=>
    string(6) "yellow"
  }
}

array_multisort - Manual, array_multisort — Sort multiple or multi-dimensional arrays We have an array of rows, but array_multisort() requires an array of columns, so we use What I didn't like about the documentation examples is that you need to loop through the​  array_multisort () can be used to sort several arrays at once, or a multi-dimensional array by one or more dimensions. Associative ( string) keys will be maintained, but numeric keys will be re-indexed. Note: If two members compare as equal, their relative order in the sorted array is undefined.

maybe this question can help you, on the other hand, maybe usort() is a choice

usort($objectListData4, 'cmp');

function cmp($a, $b) {
    return strcmp($a['name'], $b['name']);
}

usort - Manual, usort — Sort an array by values using a user-defined comparison function In that case it is better to use usort with a comparison function that takes both fields into account, but if you can't do Needed a date sort and I didn't know if one was available so I wrote one. Simulated wrong property request ( dumb property ) PHP: Sort multiple or multi-dimensional arrays The array_multisort() function is used to sort multiple arrays or a multidimensional array by one or more dimensions. Note: Associative (string) keys will be maintained, but numeric keys will be re-indexed.

Short answer: you cannot use array_multisort() to achieve what you want because if two members compare as equal, their relative order in the sorted array is undefined. (See the note in http://php.net/manual/en/function.array-multisort.php)

It means you cannot expect your "notebooks" to preserve their original order. If they happened to do it, it was just a coincidence.

Here is one solution for you.

function jnlsort($a, $b)//if the names are same, sort by index. Otherwise, sort by name.
{
    if (($a['name'] == $b['name']))
    {
        return strcmp($a['index'], $b['index']);
    }

    return strcmp($a['name'], $b['name']);
}

foreach($objectListData4 as $index => $obj)//add the index fields to preserve the order
{
    $objectListData4[$index]["index"] = $index;
}

usort($objectListData4, 'jnlsort');

foreach($objectListData4 as $index => $obj)//remove the index fields
{
    unset($objectListData4[$index]["index"]);
}

sort - Manual, This didn't work (why not?), but you can do a proper case insensitive sort like this: in a case-insensitive manner, it is a simple matter of doing usort($array, function array_qsort (&$array, $column=0, $order=SORT_ASC, $first=0, $last= -2​) The array_multisort () function returns a sorted array. You can assign one or more arrays. The function sorts the first array, and the other arrays follow, then, if two or more values are the same, it sorts the next array, and so on. Note: String keys will be maintained, but numeric keys will be re-indexed, starting at 0 and increase by 1.

PHP: array_multisort, array_multisort -- Sort multiple or multi-dimensional arrays i made it a real (​prooved) function, cause i needed to sort by two of the columns and it didn't work, sorting twice. when sorting a sql request always keep in mind the time factor. The array_multisort() can be used to sort several arrays at once, or a multi-dimensional array by one or more dimensions. Sort using array_multisort by value of 1 key Lets now see how to use the array_multisort() function to do the same sorting as the one we did using usort above.

PHP array_multisort() Function, Specifies the sorting order. Possible values: SORT_ASC - Default. Sort in ascending order (A-Z); SORT_DESC - Sort in descending order (Z-A). sorttype  I wrote this function to sort meta_value in wordpress. I tried a lot of array sorting but neither of them work. But this is not suitable for multidimensional array. This is intended only for wordpress meta_value The problem is to sort below( the order should be ascending; alphabetically then numerically like A-Z then 0-9): 500-999 users 25-49 users

Collection sortBy() on multiple fields · Issue #11 · laravel/ideas · GitHub, array_multisort() pode ser usada para ordenar vários arrays de uma vez, ou um array Pass the array, followed by the column names and sort flags What I didn't like about the documentation examples is that you need to loop through the input array to create //This just goed through and asks the additional arguments The sample function for having the sort function be a class method has a comment identifying the sorting function as static, however the function does not have the static keyword. In PHP 5 (at least as configured on my server), usort will fail, identifying the method as non-static.

Comments
  • This is documented behaviour. In the manual, for the first example, it states "The entries in the second array corresponding to the identical entries in the first array (100 and 100) were sorted as well". In your case, that would be the entries in the second array $objectListData4 corresponding to the identical "notebook" values in the first array $tmp.
  • there is no "100" in the first array. the first array contains only the key and name and thats it - no quantity.
  • The quote is referring to the example arrays, the first of which does have values of "100". In your case that is equivalent to the first array having multiple "notebook" values and the second array then being sorted on quantity. @GeorgeAppleton answer is correct and you should accept it.
  • This does fix it in this specific case. Tho not knowing what is causing it to do unrequested secondary sorting on one dataset but not another makes me wonder if this fix fixes it in every case, or if its going to be seemingly random still. And not knowing whats causing the original issue makes me wonder if this is ONLY an issue sometimes when there is only one column being sorted on, or if it can happen when there are more than 1. Would need to dig into the internals of php to find out.
  • It will fix it in any case, the code I added effectively disables further secondary sorting. Just put your sort array before and the array to be sorted after