Maple
Maple

Reputation: 183

Sort an associative array of related rows by a row of dates formatted as m/d/Y

My array has an array for each field (i.e date, name, etc.). How do I sort the array by date? Should I create another array? Can I use sort or unsort here. If yes, how? Here is my array:

Array
(
    [date] => Array
        (
            [0] => 03/11/2019
            [1] => 03/19/2019
            [2] => 03/15/2019
            [3] => 12/15/2018
        )

    [name] => Array
        (
            [0] => Lowa
            [1] => Stephanie
            [2] => Allan
            [3] => Joffer
        )

    [number] => Array
        (
            [0] => 178989898
            [1] => 111111111
            [2] => 222222222
            [3] => 333333333
        )

    [unit] => Array
        (
            [0] => HR
            [1] => VPP
            [2] => 
            [3] => OAT
        )

    [department] => Array
        (
            [0] => Chemistry
            [1] => IT
            [2] => Lab
            [3] => Contractor
        )

) 

At the end, my first element will be: 03/19/2019 Stephanie 111111111 VPP IT

Upvotes: 0

Views: 94

Answers (3)

mickmackusa
mickmackusa

Reputation: 47894

You can leave your data in the original structure and use array_multisort() to sort by the parsed dates in a descending order. Demo

$array = [
    'date' => ['03/11/2019', '03/19/2019', '03/15/2019', '12/15/2018'],
    'name' => ['Lowa', 'Stephanie', 'Allan', 'Joffer'],
    'number' => [178989898, 111111111, 222222222, 333333333],
    'unit' => ['HR', 'VPP', '', 'OAT'],
    'department' => ['Chemistry', 'IT', 'Lab', 'Contractor'],
];

array_multisort(
    array_map(fn($dmY) => date_create_from_format('d/m/Y', $dmY), $array['date']),
    SORT_DESC,
    $array['date'],
    $array['name'],
    $array['number'],
    $array['unit'],
    $array['department'],
);
var_export($array);

Upvotes: 0

MarcoS
MarcoS

Reputation: 17711

I think your data can be better organized:

$newArr = Array
(
    [0] => Array
        (
            [date] => 03/11/2019
            [name] => Lowa
            [number] => 178989898
            [unit] => HR
            [department] => Chemistry
        )

    [1] => Array
        (
            [date] => 03/19/2019
            [name] => Stephanie
            [number] => 111111111
            [unit] => VPP
            [department] => IT
        )

    [2] => Array
        (
            [date] => 03/15/2019
            [name] => Allan
            [number] => 222222222
            [unit] =>
            [department] => Lab
        )

    [3] => Array
        (
            [date] => 12/15/2018
            [name] => Joffer
            [number] => 333333333
            [unit] => OAT
            [department] => Contractor
        )
);

Then, you can simply sort it by:

function cmp($a, $b) {
  if ($a["date"] == $b["date"]) return 0;
  return ($a["date"] < $b["date"]) ? -1 : 1;
}

usort($newArr, "cmp");

Please be warned that dates in the format "Month/Day/Year" ar not alphabetically sortable.
You definitively should use a Year/Month/Day format for your dates, or write a more specific cmp() function...

UPDATE: To answer OP's question in comment: just reverse $row and 'field' order:

for ($row = 0; $row < count($date); $row++) {
  $newArr[$row]['date'] = $date[$row];
  $newArr[$row]['name'] = $name[$row];
  ...
}

Upvotes: 1

dWinder
dWinder

Reputation: 11642

First save the keys of your array - then by using array_value convert to integer keys so you can use the ... operator.

Then you can use array_filter with null function to re-organize your array. Next step will be to get the keys back using array_map and array_combine.

Last step - sort by "data" with usort

Consider the following example:

$arr = ["date" => ["3", "7", "5"], "name" => ["aa", "bb", "cc"]]; // this can have a lot more sub-array inside
$keys = array_keys($arr); // extract the keys for later use
$res = array_map(null, ...array_values($arr)); // transposed the array
$res = array_map(function ($e) use ($keys) {return array_combine($keys, $e);}, $res); // return the keys to the transposed array
usort($res, function ($a, $b) {return strcmp($a['date'], $b['date']);} ); // sort all by "date"

Reference:

array-keys, array-filter, array-map, usort, array-values

Notice @MarcoS post comment regarding the comparing dates

Upvotes: 1

Related Questions