Reputation: 87
I've got an array with 3 parameters: date, events and tags.
This is the array:
Array
(
[date] => 1554328800
[events] => Array
(
[0] => 130
[1] => 131
[2] => 163
)
[tags] => Array
(
[0] => 4
[1] => "1,3,4"
[2] => "1,3"
)
)
The relationship between events and tags is in the key, so the event 130 that has position 0 has tag 4.
As you can see there are some tags repeated (events 130 and 131 or 131 and 163).
How could I get an array with only repeated events like this:
Array
(
[0] => Array
(
[date] => 1554328800
[events] => Array
(
[0] => 130
[1] => 131
)
[tags] => 4
)
[1] => Array
(
[date] => 1554328800
[events] => Array
(
[0] => 131
[1] => 163
)
[tags] => Array
(
[0] => 1
[1] => 3
)
)
)
Upvotes: 4
Views: 104
Reputation: 350310
Here is how I would do it:
List the events per individual tag
This will give several sets of events, which can be used in the next step
List the tags per set of events that occurred in previous step
Produce the result from step 2
Here is the code, also runnable at 3v4l.org:
// Sample input
$data = [
"date" => 1554328800,
"events" => [130, 131, 163],
"tags" => [4, "1,3,4", "1,3"]
];
// 1. List the events per individual tag
foreach($data["tags"] as $i => $val) {
$vals = explode(",", $val);
foreach($vals as $val) {
$eventsByTag[$val][] = $data["events"][$i];
}
}
// 2. List the tags per set of events
foreach($eventsByTag as $tag => $events) {
sort($events, SORT_NUMERIC);
$tagsByEvents[implode(",", $events)][] = $tag;
}
// 3. produce the result
foreach($tagsByEvents as $events => $tags) {
$events = explode(",", $events);
if (count($tags) == 1) $tags = $tags[0];
$result[] = [
"date" => $data["date"],
"events" => $events,
"tags" => $tags
];
}
print_r($result);
Upvotes: 2
Reputation: 733
pl check this
$sarr=['date'=>1554328800,
'events'=>
[
130,
131,
163
],
'tags'=>
[
4,
"1,3,4",
"1,3"
]
];
$tagarr=[];
$events=$sarr['events'];
$index=0;
foreach( $sarr['tags'] as $tag)
{
$t=explode(",",$tag);
$cnt=count($t);
for($idx=0;$idx<$cnt;$idx++)
$tagarr[$t[$idx]][]=$events[$index];
$index++;
}
$cnt=count($tagarr);
$myarr=[];
foreach($tagarr as $key=>$value)
{
$myarr[]=['date'=>$sarr['date'],'events'=>$value,'tags'=>$key];
}
ec ho "<pre>";
print_r($myarr);
echo "</pre>";
output is
Array
(
[0] => Array
(
[date] => 1554328800
[events] => Array
(
[0] => 130
[1] => 131
)
[tags] => 4
)
[1] => Array
(
[date] => 1554328800
[events] => Array
(
[0] => 131
[1] => 163
)
[tags] => 1
)
[2] => Array
(
[date] => 1554328800
[events] => Array
(
[0] => 131
[1] => 163
)
[tags] => 3
)
)
Upvotes: -1
Reputation: 614
$date = array();
$date['date'] = 1554328800;
$date['events'] = array(130, 131, 163);
$date['tags'] = array(4, "1,3,4", "1,3");
$events_by_tag = array(); //gather events grouped by tag
foreach ($date['events'] as $pos => $event) { //parse all events
if (is_string($date['tags'][$pos])) { //if tag is a string <=> if there are more than one tag for the current event
$tags = explode(',', $date['tags'][$pos]); //explode string to loop over the tags
foreach ($tags as $tag) {
if (is_array($events_by_tag[$tag])) { //if tag has already been found and then an array exists to store it
array_push($events_by_tag[$tag], $event);
} else {
$events_by_tag[$tag] = array($event); //else create an array for the next times this tag will be found and store it inside
}
}
} else { //if there's a single tag which is a integer
if (is_array($events_by_tag[$tag])) { //if tag has already been found and then an array exists to store it
array_push($events_by_tag[$date['tags'][$pos]], $event);
} else {
$events_by_tag[$date['tags'][$pos]] = array($event); //else create an array for the next times this tag will be found and store it inside
}
}
}
$result_array = array(); //final array reorganized + date
foreach ($events_by_tag as $tag => $events) {
$tmp_array['date'] = $date['date'];
$tmp_array['events'] = $events;
$tmp_array['tags'] = $tag;
array_push($result_array, $tmp_array);
}
This is NOT exactly what you expected because it will not merge events sharing tags. I think this part needs another post to be developed, but otherwise I can modify my answer to give you the way to go if necessary.
Upvotes: -1