Radza Milic Radza Milic - 3 months ago 16
PHP Question

Sort laravel 5.1 collection response by date

I get a response from a API call that looks something like this:

[
{
date: {
date: "2016-08-03 08:17:18.000000",
timezone_type: 3,
timezone: "CET"
},
pageTitle: "Page 1",
visitors: 3,
pageViews: 27
},
{
date: {
date: "2016-08-03 08:17:18.000000",
timezone_type: 3,
timezone: "CET"
},
pageTitle: "Page 2",
visitors: 2,
pageViews: 13
},
{etc...}
]


It returns visitors for each page for each day. I would like to filter so that it returns the combined visitors for all the pages per day. I figured I would need to sort it by date first (day). I tried something like this without success:

->groupBy(function($item){
return $item->date->date->format('d-M-y')
)});


Some help would be great

Answer

Since your API Response is JSON, you may need to start by converting the JSON Data to Standard PHP Object and then using foreach build a new Collection to suit your needs.... The Commented Code below shows the steps clearly and you may even also test a simulated Example of this here:

<?php 

    // SIMULATE A JSON STRING (BASED ON YOUR DATA) TO BE CONVERTED TO PHP OBJECT
    // JUST FOR TESTING PURPOSES...
    $apiResponse = '[
        {
            "date": {
                "date": "2016-08-03 08:17:18.000000",
                "timezone_type": 3,
                "timezone": "CET"
            },
            "pageTitle": "Page 1",
            "visitors": 3,
            "pageViews": 27
        },
        {
            "date": {
                "date": "2016-08-03 08:17:18.000000",
                "timezone_type": 3,
                "timezone": "CET"
            },
            "pageTitle": "Page 2",
            "visitors": 2,
            "pageViews": 13
        }
    ]';


    // DECODE THE JSON DATA BACK INTO PHP OBJECT
    $data   = json_decode($apiResponse);

    // CREATE AN ARRAY TO HOLD THE FILTERED RESULT
    $sorted = [];

    // LOOP THROUGH THE DATA ($data) & THEN TO CHECK IF EACH ENTRY THROUGH THE ITERATION
    // HAS SIMILAR DATES (WITHOUT THE TIME PART)
    // IF IT DOES THEN ADD MERGE THE DATA TOGETHER AND PUSH IT TO THE ARRAY: $sorted...
    foreach($data as $k=>$item){
        // GET ONLY THE DATE PORTION WITHOUT THE TIME....
        $dateNoTime     = current(explode(" ", $item->date->date));
        if(!array_key_exists($dateNoTime, $sorted)){
            $sorted[$dateNoTime]                    = $item;
        }else{
            $pageViews  = $sorted[$dateNoTime]->pageViews;
            $visitors   = $sorted[$dateNoTime]->visitors;
            $pageTitle  = $sorted[$dateNoTime]->pageTitle;
            $sorted[$dateNoTime]->pageViews   = $pageViews + $item->pageViews;
            $sorted[$dateNoTime]->visitors    = $visitors  + $item->visitors;
            $sorted[$dateNoTime]->page_title  = ($pageTitle != $item->pageTitle) ?
                                                ($pageTitle . ", {$item->pageTitle}") : $pageTitle;
        }
    }

    var_dump($sorted);
    // PRODUCES::
    array (size=1)
      '2016-08-03' => 
        object(stdClass)[223]
          public 'date' => 
            object(stdClass)[221]
              public 'date' => string '2016-08-03 08:17:18.000000' (length=26)
              public 'timezone_type' => int 3
              public 'timezone' => string 'CET' (length=3)
          public 'pageTitle' => string 'Page 1' (length=6)
          public 'visitors' => int 5
          public 'pageViews' => int 40
          public 'page_title' => string 'Page 1, Page 2' (length=14)

In your case, the Effective Code would thus be:

<?php 

    $data   = json_decode($apiResponse); //<== WHERE $apiResponse IS YOUR RESPONSE
    $sorted = [];
    foreach($data as $k=>$item){
        $dateNoTime     = current(explode(" ", $item->date->date));
        if(!array_key_exists($dateNoTime, $sorted)){
            $sorted[$dateNoTime]              = $item;
        }else{
            $pageViews  = $sorted[$dateNoTime]->pageViews;
            $visitors   = $sorted[$dateNoTime]->visitors;
            $pageTitle  = $sorted[$dateNoTime]->pageTitle;
            $sorted[$dateNoTime]->pageViews   = $pageViews + $item->pageViews;
            $sorted[$dateNoTime]->visitors    = $visitors  + $item->visitors;
            $sorted[$dateNoTime]->page_title  = ($pageTitle != $item->pageTitle) ?
                                                ($pageTitle . ", {$item->pageTitle}") : $pageTitle;
        }
    }

    // THE VARIABLE CONTAINING YOUR RESULT IS: $sorted  ;-)

UPDATE: SORTING — WITH THE KEYS "visitors", "formattedDate", FIRST

<?php

    $data               = json_decode($apiResponse);
    $sorted             = [];
    foreach($data as $k=>$item){
        $dateNoTime     = current(explode(" ", $item->date->date));
        if(!array_key_exists($dateNoTime, $sorted)){
            $sorted[$dateNoTime]                = new stdClass();
            $sorted[$dateNoTime]->visitors      = $item->visitors;
            $sorted[$dateNoTime]->formattedDate = $dateNoTime;
            $sorted[$dateNoTime]->pageViews     = $item->pageViews;
            $sorted[$dateNoTime]->pageTitle     = $item->pageTitle;
            $sorted[$dateNoTime]->date          = $item->date;
        }else{
            $pageViews  = $sorted[$dateNoTime]->pageViews;
            $visitors   = $sorted[$dateNoTime]->visitors;
            $pageTitle  = $sorted[$dateNoTime]->pageTitle;
            $sorted[$dateNoTime]->pageViews     = $pageViews + $item->pageViews;
            $sorted[$dateNoTime]->visitors      = $visitors  + $item->visitors;
            $sorted[$dateNoTime]->pageTitle     = ($pageTitle != $item->pageTitle) ?
                ($pageTitle . ", {$item->pageTitle}") : $pageTitle;
        }
    }
    $sorted  = array_values($sorted);

    // GET THE FIRST "OBJECT" IN THE COLLECTION:
    $objData = current($sorted);

    // GET THE NEXT (2ND) "OBJECT" IN THE COLLECTION:
    $objData = next($sorted);  //<== RETURNS false IF THERE IS NONE...

    // GET THE 3RD "OBJECT" IN THE COLLECTION:
    $objData = next($sorted);  //<== RETURNS false IF THERE IS NONE...

Cheers & Good-Luck!!!

Comments