madoreo
madoreo

Reputation: 33

Multisorting 2d array by first row alphabetically, then by second row's "j F Y" dates

I have everything in place with no errors and everything seems correct. I am trying to output the names and dates in ascending order while using print_r() to verify the order.

$win = array(
    'Name' => array(
        'Jane Doe ',
        'Nash Patel ',
        'Joe Public '
    ), 
    'Date' => array(
        '7 October 2015 ',
        '14 October 2014 ',
        '12 October 2016 '
    )
);

foreach($win as $element => $namedate) {
    echo '<strong>' . $element . '</strong><br>';
    foreach($namedate as $both) {
        echo $both . '<br/>';
    }
}

foreach ($win as $c => $key) {
    $sort_date[] = $key['Date'];
    $sort_name[] = $key['Name'];
}
array_multisort($sort_name, SORT_ASC, $sort_date, SORT_ASC, $win);
print_r($win);

OUTPUT\

Array (
    [Date] => Array (
        [0] => 7 October 2015 
        [1] => 14 October 2014 
        [2] => 12 October 2016 
    )
    [Name] => Array (
        [0] => Jane Doe 
        [1] => Nash Patel 
        [2] => Joe Public 
    )
)

Upvotes: 0

Views: 78

Answers (3)

mickmackusa
mickmackusa

Reputation: 47894

When using multisort, all array arguments MUST contain the same element count. You do not need to append $win as the last argument to affect the previously declared elements.

When passing arguments to the function, any arrays which can be modified by reference will be mutated. Any arguments which are derived directly from a function return, will not be affected (and couldn't be retrieved anyhow).

Because the date format is not "big endian", you need to transform it into a set of values which can be simply sorted. Calling strtotime() on each value will suitably produce unix timestamp integers.

Code: (Demo)

array_multisort(
    $win['Name'],
    array_map('strtotime', $win['Date']),
    $win['Date']
);
var_export($win);

Upvotes: 0

Andreas
Andreas

Reputation: 23958

Because you say the arrays don't need to be sorted together here is how to split them and sort them separately.

$win = array('Name'=> 
                    array('Jane Doe ', 'Nash Patel ', 'Joe Public '), 
         'Date'=>
                    array('7 October 2015 ', '14 October 2014 ', '12 October 2016 '));


$dates = $win["Date"]; //split array
$names = $win["Name"]; //split array

usort($dates, "date_sort"); // custom sort on dates
asort($names); // sort names

var_dump($dates);
Var_dump($names);


function date_sort($a, $b) {
    return strtotime($a) - strtotime($b);
}

https://3v4l.org/kLjRh

Output:

array(3) {
  [0]=>
  string(16) "14 October 2014 "
  [1]=>
  string(15) "7 October 2015 "
  [2]=>
  string(16) "12 October 2016 "
}

 array(3) {
  [0]=>
  string(9) "Jane Doe "
  [2]=>
  string(11) "Joe Public "
  [1]=>
  string(11) "Nash Patel "
}

Upvotes: 0

Greg
Greg

Reputation: 6636

I've read the docs and it seems that

array_multisort($sort_name, SORT_ASC, $sort_date, SORT_ASC, $win);

means that $win will be sorted by name and date, but sorting by name has bigger priority over date.

Try adding more Jane Doe with different dates to see that they're sorted with date.

Upvotes: 1

Related Questions