JasonK JasonK - 5 months ago 24
PHP Question

Advanced array rebuilding in PHP

I'm predicting user interests based on tag associations. These associations will be plotted in a multi-line chart using ChartJS. I got to the point where the data format is almost ready to be used on the client-side.

Don't get scared by the array's size. My question is rather simple, but tricky to solve, so it seems.

Consider the following array (including example data):

array:3 [▼
"timespan" => "day",
"labels" => array:3 [▼ // Date labels based on timespan
0 => "2016-06-10"
1 => "2016-06-11"
2 => "2016-06-12"
],
"data" => array:2 [▼
0 => array:3 [▼
"id" => 16473,
"name" => "FooTag"
"timeline" => array:3 [▼
0 => array:3 [▼
"Date" => "2016-06-10"
"Frequency" => 2
"Score" => 4.0
]
1 => array:3 [▼
"Date" => "2016-06-12"
"Frequency" => 2
"Score" => 4.0
]
]
]
1 => array:3 [▼
"id" => 10814,
"name" => "BarTag"
"timeline" => array:1 [▼
0 => array:3 [▼
"Date" => "2016-06-10"
"Frequency" => 2
"Score" => 3.0
],
1 => array:3 [▼
"Date" => "2016-06-11"
"Frequency" => 10
"Score" => 20.0
]
]
]
]
]


...make sure every date label (2016-06-10, 206-06-11, 2016-06-12) is covered for every timeline within
data[i][timeline]
. If there is no data available in the timeline for that specific date label, an empty array must be inserted.

The result would be:

array:3 [▼
"labels" => array:3 [▼ // Date labels based on timespan
0 => "2016-06-10"
1 => "2016-06-11"
2 => "2016-06-12"
]
"timespan" => "day"
"data" => array:2 [▼
0 => array:3 [▼
"id" => 16473,
"name" => "FooTag"
"timeline" => array:3 [▼
0 => array:3 [▼
"Date" => "2016-06-10"
"Frequency" => 2
"Score" => 4.0
],
1 => array:0 [], // No data for label 2016-06-11, empty array added
2 => array:3 [▼
"Date" => "2016-06-12"
"Frequency" => 2
"Score" => 4.0
]
]
]
1 => array:3 [▼
"id" => 10814,
"name" => "BarTag"
"timeline" => array:1 [▼
0 => array:3 [▼
"Date" => "2016-06-10"
"Frequency" => 2
"Score" => 3.0
],
1 => array:3 [▼
"Date" => "2016-06-11"
"Frequency" => 10
"Score" => 20.0
],
2 => array:0 [], // No data for label 2016-06-12, empty array added
]
]
]
]


In this case every associated tag has data for every date. Otherwise the data (frequency and score) wouldn't match the right date when plotting the chart.

I hope this makes sence. Thanks in advance!

Answer

Assuming $array['labels'] is the definitive list of dates, and $array['data'][$i]['timeline'] will always be sorted in ascending order and never contain dates not in $array['labels']:

$labels = $array['labels'];

foreach ($array['data'] as &$tag) {
   foreach ($labels as $i => $date) {
      if (!isset($tag['timeline'][$i]) || $tag['timeline'][$i]['Date'] != $date) {
         $blank = [];
         array_splice($tag['timeline'], $i, 0, [$blank]);
      }
   }
}
Comments