简体   繁体   中英

How to sort multidimensional array in PHP version 5.4?

I have an array structure whose print_r output looks like this:

Array
(
    [0] => Array
        (
            [0] => Game
            [1] => Date
            [2] => Site
            [3] => Address
            [4] => FirstName
            [5] => LastName
            [6] => Email
            [7] => Phone
        )

    [1] => Array
        (
            [0] => B-Dry @ Blue Wave DH
            [1] => 7/9/2019 13:00
            [2] => Blue Wave Dover City Park
            [3] => Dover
            [4] => John
            [5] => Doe
            [6] => john.doe@perrylocal.org
            [7] => (555) 555-4797
        )

    [2] => Array
        (
            [0] => B-Dry @ Blue Wave DH
            [1] => 7/9/2019 13:00
            [2] => Blue Wave Dover City Park
            [3] => Dover
            [4] => Frank
            [5] => Sinatra
            [6] => frank@sinatra.com
            [7] => (555) 685-5555
        )

    [3] => Array
        (
            [0] => B-Dry @ Gnaden
            [1] => 6/7/2019 18:00
            [2] => Gnaden Indian Valley HS
            [3] => Gnadenhutten
            [4] => Jimmy
            [5] => Dean
            [6] => jimmy@dean.org
            [7] => (330) 555-5555
        )
   [...many more...]
)

The data comes from an excel spreadsheet. If it came from SQL, sorting would be trivial. :-)

How can I sort/resequence this array as follows:

  1. ignore first array set (column labels, not data)
  2. sort first by index 0 (ex: "B-Dry @ Blue Wave DH")
  3. sort second by index 1 (ex: "7/9/2019 13:00")
  4. sort third by index 2 (ex: "Blue Wave Dover City Park")

This post seems promising, but I believe that array_column works only in PHP 5.5 which I cannot upgrade to yet. And I'm unsure how to exclude the first array set (column labels) in all cases.

Here is a function that will sort your multidimensional array by the amount of columns you want:

function mult_usort(&$arr, $max_index = false, $index = 0) {

    // Done on purpose, could not use a closure
    function mult_usort_callback($a, $b, $max_index, $index) {
        $max_index = $max_index ?: (count($a) - 1);

        // Recursive to sort till the max index
        if ($a[$index] == $b[$index]) {
            if ($index < $max_index) {
                return mult_usort_callback($a, $b, $max_index, ($index + 1));
            } else {
                return 0;
            }
        }
        return $a[$index] > $b[$index] ? 1 : -1;
    };

    usort($arr, create_function('$a, $b', 'return mult_usort_callback($a, $b, ' . $max_index . ', ' . $index . ');'));
}

And use it like:

// Remove the 1st item
array_shift($data);

// Change the date & time column to DateTime objects for proper comparison
// DateTime: PHP >= 5.2
$data = array_map(function ($item) {
    $item[1] = DateTime::createFromFormat('d/m/Y H:i', $item[1]);
    return $item;
}, $data);

// Then sort with the function, till index 2
mult_usort($data, 2);

This function uses:


If your data is the result of a SQL query, you better ORDER inside your query, this will be easier and faster .
See also: updated function for associative arrays

To get rid of the first element, simply:

unset($array[0]);

And then use usort function along with DateTime comparison:

    <?php

$data = [
    [
            'Game',
            'Date',
            'Site',
            'Address',
            'FirstName',
            'LastName',
            'Email',
            'Phone'
    ],
    [
            'B-Dry @ Gnaden',
            '6/7/2019 18:00',
            'Gnaden Indian Valley HS',
            'Gnadenhutten',
            'Jimmy',
            'Dean',
            'jimmy@dean.org',
            '(330) 555-5555'
    ],
    [
            'B-Dry @ Blue Wave DH',
            '7/9/2019 19:00',
            'Blue Wave Dover City Park',
            'Dover',
            'John',
            'Doe',
            'john.doe@perrylocal.org',
            '(555) 555-4797'
    ],
    [
            'B-Dry @ Blue Wave DH',
            '7/9/2019 13:00',
            'Blue Wave Dover City Park',
            'Dover',
            'Frank',
            'Sinatra',
            'frank@sinatra.com',
            '(555) 685-5555'
    ]
];

    unset($data[0]);

    usort($data, function ($a, $b) {
       if ($a[0] == $b[0]) {
           $d1 = DateTime::createFromFormat('d/m/y h:i',$a[1]);
           $d2 = DateTime::createFromFormat('d/m/y h:i',$b[1]);
           if ($d1 == $d2) {
                if ($a[2] == $b[2]) {
                    return 0;
                }
                return ($a[2] < $b[2]) ? -1 : 1;
           }
           return ($d1 < $d2) ? -1 : 1;
       }
       return ($a[0] < $b[0]) ? -1 : 1;
    });

    var_dump($data, true);

Checked at: https://3v4l.org/uMacS

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM