mchev mchev - 2 months ago 9
PHP Question

PHP get distinct ids count from an array by date

Looking for the simplest way to achieve the following in php:

I have this array with dates and ids

$data = array(
array("date" => "2016-01", "ids" => array(1,2,3,4,5,6,7,8)),
array("date" => "2016-02", "ids" => array(1,2,9,10,11,12)),
array("date" => "2016-03", "ids" => array(3,16,17,18,19,20,21)),
array("date" => "2016-04", "ids" => array(1,2,3,19,20,22,23))
);


The idea is to count ids by date but also return count(existing ids) since the start of every month separately. (I hope this is understandable)

The returned array should look like this:

$data = array(
array("date" => "2016-01", "counter" => array(8)),
array("date" => "2016-02", "counter" => array(2,4)), /* 2 existing ids from 2016-01 and 4 new in 2016-02) */
array("date" => "2016-03", "counter" => array(1,0,6)), /* 1 existing from 2016-01 and 0 exiting from 2016-02 and 6 new */
array("date" => "2016-04", "counter" => array(3,0,2,2)) /* etc. */
);



| 2016-01 | 2016-02 | 2016-03 | 2016-04
------ | ------- | ------- | ------- | -------
2016-01 | 8 | | |
------ | ------- | ------- | ------- | -------
2016-02 | 2 | 4 | |
------ | ------- | ------- | ------- | -------
2016-03 | 1 | 0 | 6 |
------ | ------- | ------- | ------- | -------
2016-04 | 3 | 0 | 2 | 2


Of course if there is a way to do that directly in sql i'll take it :)

Answer

You can do something like this to achieve the desired result,

$newArray = array();
$count = count($data);
for($i = 0; $i < $count; ++$i){
    $newArray[$i] = array('date' => $data[$i]['date'], 'counter' => array());
    for($j = 0; $j < $i; ++$j){
        $counter = 0;
        foreach($data[$i]['ids'] as $key => $id){
            if(in_array($id, $data[$j]['ids'])){
                ++$counter;
                unset($data[$i]['ids'][$key]);
            }
        }
        $newArray[$i]['counter'][] = $counter;
    }
    $newArray[$i]['counter'][] = count($data[$i]['ids']);
}

// display $newArray array
var_dump($newArray);

Here's the live demo