J Young
J Young

Reputation: 755

Sort a multi-dimensional array based on an ordered array

This seems the oldest question in the book with hundreds of resources available, but so far each solution I have tried has not solved my problem. I'm hoping you can help.

I'm trying to display a graph that displays the last 31 days of data. The outputted array looks like this:

$data[
    0 =>
       'day' => 10,
       'amount' => 5,
       'count' => 2
    1 =>
       'day' => 16,
       'amount' => 4,
       'count' => 2
    2 =>
       'day' => 21,
       'amount' => 16,
       'count' => 1
    3 =>
       'day' => 11,
       'amount' => 0,
       'count' => 0
    4 =>
       'day' => 12,
       'amount' => 0,
       'count' => 0
]

Essentially this array is composed of two parts. The first 3 inner arrays are days that contain amounts and counts, the remaining 27 are any unaccounted for days with their amounts and counts set to 0. So for example $data[5] will be day 13 and $data[21] day 31. $data[22] will then equal day 1, going up to day 9 thus therefore showing the last 31 days.

In addition there is an ordered array of the days we want to output.

$days[
    0 =>
        'day' => 10
    1 =>
        'day' => 11
    2 =>
        'day' => 12
    ...
    30 =>
        'day' => 9
]

I have tried the below but whilst $data is now ordered, it's essentially just a replica of $days and loses the other values held in $data.

$data = array_uintersect($days, $data, array($this, 'compare_days'));

function compare_days($order, $array) {
    return strcmp($order['day'], $array['day']);
}  

What's up? How can I sort $data so that it retains the data and orders it as desired in $days?

Upvotes: 4

Views: 141

Answers (2)

Vikramraj
Vikramraj

Reputation: 198

You can use this:

foreach ($data as $key => $row) {
    $days[$key]  = $row['day'];
    $amount[$key] =  $row['amount'];
}

array_multisort($days, SORT_ASC, $amount, SORT_ASC, $data);

print_r($data);

Upvotes: 0

Narendrasingh Sisodia
Narendrasingh Sisodia

Reputation: 21437

Simply use uasort as

uasort($data, function($a,$b) use ($days){
    foreach($days as $value){
        if($a['day'] == $value['day']){
            return 0;
            break;
        }
        if($b['day'] == $value['day']){
            return 1;
            break;
        }
    }
});

Demo

Upvotes: 3

Related Questions