1

I have an array that looks like this:

Array
(
    [0] => Array
        (
            [0] => A
            [1] => -1
            [2] => -1
        )

    [1] => Array
        (
            [0] => B
            [1] => 0
            [2] => 1
        )

    [2] => Array
        (
            [0] => C
            [1] => -1
            [2] => 0
        )

)

My objective is to sort this array by each nested array, meaning that I want to sort the array by the values of [1] in each, then by the values of [2] in each, etc. My current code is below, and I can understand why it doesn't provide the result that I want. Each time the loop passes through, it overrides $csvarray and I get just multiples of the same thing.

I want to put each sorted array into its own array so I can display them in an HTML table later. I've tried setting variables using $i but have had no success.

for ($i = 1; $i < count($csvarray); $i++) {
    uasort($csvarray, function($a, $b) {
        return $b[$i] <=> $a[$i];
    });

    echo "<pre>";
    print_r($csvarray);
    echo "</pre>"; 

}

User AbraCadaver gave me the correct answer for what I was looking for, with the following:

for ($i = 1; $i < count($csvarray); $i++) {
    array_multisort(array_column($csvarray, $i), SORT_DESC,
                    $csvarray, SORT_DESC);


    echo "<pre>";
    print_r($csvarray);
    echo "</pre>"; 

} 
user121106
  • 15
  • 3
  • What is the desired output? – u_mulder Jun 14 '17 at 20:03
  • @u_mulder For this loop I would have an array for each sort that I plan to json encode and run through a web API. The issue is that the CSVs that make up the original array will have variable column amounts, which is why I need the loop in the first place. I'd have an array that's sorted DESC by the values of the nested [1], then an array sorted by nested [2], etc. – user121106 Jun 14 '17 at 20:05
  • `usort($csv, function ($a, $b) { return $a[0] <=> $b[0] ?: $a[1] <=> $b[1] ...; })` – You need to put the loop (or an `array_reduce`) *inside* the comparison function. – deceze Jun 14 '17 at 20:28

1 Answers1

0

I would just extract those columns, sort them and then sort the original:

array_multisort(array_column($csvarray, 1), SORT_DESC,
                array_column($csvarray, 2), SORT_DESC,
                $csvarray, SORT_DESC);

If you want SORT_ASC (ascending), then you can omit those arguments entirely as that is the default.

For a dynamic number of columns you could try this:

foreach($csvarray as $row) {
    array_shift($row);
    $values[] = implode('|', $row);
}
array_multisort($values, $csvarray);
AbraCadaver
  • 73,820
  • 7
  • 55
  • 81
  • I added this comment to my original post, but the CSVs I upload will have variable amounts of columns based on the analysis. Would this be possible in a loop for $i from 1 to X(however many columns I have in that particular CSV)? I need be able to extract the order of [0] from it at the end. – user121106 Jun 14 '17 at 20:09
  • But you want to ignore the 0 index? – AbraCadaver Jun 14 '17 at 20:16
  • This actually worked exactly how I wanted it to! I added the result to my original post. Thanks so much. – user121106 Jun 14 '17 at 20:28