4

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?

2 Answers 2

3

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

Sign up to request clarification or add additional context in comments.

4 Comments

This is good and sorts as intended, so thank you! The only issue now is (and I did not mention this in my post so my apologies) running a json_encode($data) returns {"5":{"day":"10","amount":"0","donations":"0"},"2":{"day":"11"... which instead needs to read [{"day":"10"...}]. I'm guessing it's because the array is now "unordered" in terms of index key. Would you any idea?
Sorry can't get you can you post the original array along with the expected output
All is fine. I solved it with echo json_encode(array_values($graph)); which fortunately resets the array indexes to be sequential. Thank you for your help!
You're welcome.Glad it helped you. And also for sequential array indexes simply use usort if you need main index to be 0,1,..
0

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);

1 Comment

This sorts by day in ascending order (1 to 31). The day actually starts on the 10th Jul (10th Aug - 31 days) and then works its way back up to the 10th August.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.