0

It's 3am here, i'm super tired and I have no idea how to make this thing to work. The following array is returned from database and contains info like page views, date and messages for the last 7 days:

Array
(
  [0] => Array
    (
        [vws] => 9
        [mss] => 0
        [dt] => 2016-06-27
    )

  [1] => Array
    (
        [vws] => 4
        [mss] => 0
        [dt] => 2016-06-26
    )

  [2] => Array
    (
        [vws] => 1
        [mss] => 0
        [dt] => 2016-06-24
    )

  [3] => Array
    (
        [vws] => 7
        [mss] => 0
        [dt] => 2016-06-23
    )

)

This array should contain data even if there are no page views or messaged so this is what i'm looking for:

Array
(
  [0] => Array
    (
        [vws] => 0
        [mss] => 0
        [dt] => 2016-06-22
    )

  [1] => Array
    (
        [vws] => 13
        [mss] => 1
        [dt] => 2016-06-23
    )

  [2] => Array
    (
        [vws] => 7
        [mss] => 3
        [dt] => 2016-06-24
    )

  [3] => Array
    (
        [vws] => 45
        [mss] => 10
        [dt] => 2016-06-25
    )

  [4] => Array
    (
        [vws] => 0
        [mss] => 0
        [dt] => 2016-06-26
    )

  [5] => Array
    (
        [vws] => 0
        [mss] => 0
        [dt] => 2016-06-27
    )

  [6] => Array
    (
        [vws] => 5
        [mss] => 1
        [dt] => 2016-06-28
    )

)

Sorry if I was not clear enough. I will update my question if you need more info. Thank you in advance

EDIT It seems that using dt value as a key is a good idea but I still think that the same result could be achieved more easily by checking dt value with in_array.

Thanks to @ArtisiticPhoenix , this code works just fine for now:

    $new = [];
    foreach ($data as $k => $v) {
        $new[$v['dt']] = $v;
    }

    $Date = new DateTime();
    $days = [];
    for ($i = 0; $i < 7; ++$i) {
        $days[$Date->format('Y-m-d')] = [
            'vws' => 0,
            'mss' => 0,
            'dt'  => $Date->format('Y-m-d')
        ];
        $Date->modify('-1 days');
    }
    $final = array_merge($days, $new);
3
  • Are you saying you want it to default to the data in the bottom column? Commented Jun 29, 2016 at 0:40
  • You can either prepare your array by creating a date range for the last 7 days and fill up the entire array with empty values and then replace it with the values you have OR you get the array with the values and then go through the last 7 days and add the ones that are missing. Get stuck? Add your current code/attempt. Commented Jun 29, 2016 at 0:41
  • I tried to put in an array the last 7 day and check with in_array in loop but for some reason, the missing days are placed at the beginning or at the end of the final array Commented Jun 29, 2016 at 0:55

1 Answer 1

1

First build an array of each day with empty values

 //current date
$Date = new DateTime();

$days = array();
 //loop 7 times, seven days in the week  ( forget if it should be <= ) 7s to high for me to count in my head right now. :)~
for($i = 0; $i<7; ++$i ){
    $days[$Date->format('Y-m-d')] = array(
        'vws' => 0,
        'mss' => 0,
        'dt' => $Date->format('Y-m-d')  
    );
    //subtract 1 day from today's date.
    $DateTime->modify('-1 days');
}

Next, use array_merge to merge that with the db data

 $data = array_merge( $days, $dbDays );

Note the keys in the prepared array is the date. You'll want to add that to the db populated data as well, this makes array_merge replace those values instead of appending the entries on ( like it would do if they where just numbered indexes ). In any case it makes correlating the data so much easier

Alternatively you could add them in in the while loop from the db, like this

while( false !== ( $row = $stmt->fetch() ) ){
    $days[$row['dt']] = $row;
}

But I am not sure where the data comes from ( mysql_ mysqli_ PDO )

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

2 Comments

Sorry for the messy comment. I forgot how to use SO markdown :). I've just updated my question and I added the working code. Is there a way to make it a bit more efficient? Thank you
Not really, you could manually do the date, but when you consider if a week ( 7 days ) crosses a month boundary or year boundary, it becomes a lot harder. For something like 7 days, performance isn't gonna be an issue. No matter how you slice it you still need to know the dates for the 7 day period.

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.