Skip to content
Advertisement

PHP order by value of array key

I have an array being created which contains a date:

$arr = array();
$arr["one"][] = array(
    'due' => '17-01-2021 10:00:00',
);
$arr["one"][] = array(
    'due' => '17-01-2021 09:00:00',
);
$arr["two"][] = array(
    'due' => '19-01-2021 09:00:00',
);
$arr["two"][] = array(
    'due' => '18-01-2021 09:00:00',
);

And I want to order by the value of the ‘due’ key

I tried adding this uasort function:

uasort($arr, function ($a, $b) {
    return $a["due"] <=> $b["due"];
});

print_r($arr);

But that still shows in the order above, whereas it should be showing the ’09:00:00′ value first

Advertisement

Answer

Your approach wasn’t really that far off, I basically just changed a few little things:

  1. Loop over each “word-number-indexed” array individually (those indexed under one and two in the main array $arr).
  2. Convert the due dates/times to unix timestamps to have an integer that can be compared. Without this, PHP tries to sort the strings on a character-by-character basis which does not work with your format but would work if your format was YYYY-MM-DD hh:mm:ss (because the “biggest” position value would be at the start).
  3. Use usort instead of uasort since there is no point in keeping the keys (which are integers to begin with and neither one nor due in this context.
$arr = array();
$arr["one"][] = array(
    'due' => '17-01-2021 10:00:00',
);
$arr["one"][] = array(
    'due' => '17-01-2021 09:00:00',
);
$arr["two"][] = array(
    'due' => '19-01-2021 09:00:00',
);
$arr["two"][] = array(
    'due' => '18-01-2021 09:00:00',
);


foreach ($arr as &$numberIndex) {
    usort($numberIndex, function ($a, $b) {
        return strtotime($a["due"]) <=> strtotime($b["due"]);
    });
}

print_r($arr);

Some side notes:

  • Note the & at &$numberIndex, without this PHP works on an in-place copy of your value and it is never changed in $arr.
  • This approach with strototime() only works if all your dates/times are after epoch time 0 (which is 1st of January 1970). If you need to use older dates you can create DateTime() objects within the sort callback.

The resulting array looks like this:

Array
(
    [one] => Array
        (
            [0] => Array
                (
                    [due] => 17-01-2021 09:00:00
                )

            [1] => Array
                (
                    [due] => 17-01-2021 10:00:00
                )

        )

    [two] => Array
        (
            [0] => Array
                (
                    [due] => 18-01-2021 09:00:00
                )

            [1] => Array
                (
                    [due] => 19-01-2021 09:00:00
                )

        )

)
User contributions licensed under: CC BY-SA
1 People found this is helpful
Advertisement