Php 合并单个数据集中的关联数据
我已经接管了一个已经包含大量数据的项目。 给定的格式不是最佳格式,只包含单个数据集。其中大多数属于同一“事件”。我想合并这些数据集 给定的数据集采用以下格式: 给定数据集:Php 合并单个数据集中的关联数据,php,algorithm,sorting,multidimensional-array,Php,Algorithm,Sorting,Multidimensional Array,我已经接管了一个已经包含大量数据的项目。 给定的格式不是最佳格式,只包含单个数据集。其中大多数属于同一“事件”。我想合并这些数据集 给定的数据集采用以下格式: 给定数据集: [0] => Array ( [id] => 4 [title] => Party 1 [start] => 2017-06-14 [end] => 2017-06-14 [className] =>
[0] => Array
(
[id] => 4
[title] => Party 1
[start] => 2017-06-14
[end] => 2017-06-14
[className] => Array
(
[0] => yyy
[1] => zzz
)
[color] => #26B99A
[zeit] => xxx
)
[1] => Array
(
[id] => 6
[title] => Party 2
[start] => 2017-04-27
[end] => 2017-04-27
[className] => Array
(
[0] => xxx
[1] => yyy
)
[color] => #26B99A
[zeit] => zzz
)
[2] => Array
(
[id] => 7
[title] => Party 2
[start] => 2017-04-28
[end] => 2017-04-28
[className] => Array
(
[0] => xxx
[1] => yyy
)
[color] => #26B99A
[zeit] => zzz
)
[3] => Array
(
[id] => 9
[title] => Party 2
[start] => 2017-04-29
[end] => 2017-04-29
[className] => Array
(
[0] => xxx
[1] => yyy
)
[color] => #26B99A
[zeit] => zzz
)
[4] => Array
(
[id] => 11
[title] => Party 3
[start] => 2017-07-30
[end] => 2017-07-30
[className] => Array
(
[0] => xxx
[1] => yyy
)
[color] => #26B99A
[zeit] => zzz
)
[5] => Array
(
[id] => 13
[title] => Party 3
[start] => 2017-07-31
[end] => 2017-07-31
[className] => Array
(
[0] => xxx
[1] => yyy
)
[color] => #26B99A
[zeit] => zzz
)......
function formateEvents($event_array){
$events = array();
foreach($event_array as $event)
{
if(!isset($events[$event['title']]))
{
$events[$event['title']]['id'] = $event['id'];
$events[$event['title']]['title'] = $event['title'];
$events[$event['title']]['start'] = $event['start'];
$events[$event['title']]['end'] = $event['end'];
$events[$event['title']]['name'] = $event['title'];
$events[$event['title']]['className'] = $event['className'];
$events[$event['title']]['color'] = $event['color'];
$events[$event['title']]['zeit'] = $event['zeit'];
}else{
if(strtotime($event['start']) < strtotime($events[$event['title']]['start']))
{
$events[$event['title']]['start'] = $event['start'];
}
if(strtotime($event['end']) > strtotime($events[$event['title']]['end']))
{
$events[$event['title']]['end'] = $event['end'];
}
}
}
return array_values($events);
}
在这种情况下,将有一个单独的“第一方”,并合并“第二方”和“第三方”
因此,结果应如下所示:
预期结果
[0] => Array
(
[id] => 4
[title] => Party 1
[start] => 2017-06-14
[end] => 2017-06-14
[className] => Array
(
[0] => yyy
[1] => zzz
)
[color] => #26B99A
[zeit] => xxx
)
[1] => Array
(
[id] => 6
[title] => Party 2
[start] => 2017-04-27
[end] => 2017-04-29 <---- end date edited
[className] => Array
(
[0] => xxx
[1] => yyy
)
[color] => #26B99A
[zeit] => zzz
)
[2] => Array
(
[id] => 11
[title] => Party 3
[start] => 2017-07-30
[end] => 2017-07-31 <---- same
[className] => Array
(
[0] => xxx
[1] => yyy
)
[color] => #26B99A
[zeit] => zzz
)
[0]=>数组
(
[id]=>4
[标题]=>第一方
[开始]=>2017-06-14
[完]=>2017-06-14
[className]=>数组
(
[0]=>yyy
[1] =>zzz
)
[颜色]=>#26B99A
[zeit]=>xxx
)
[1] =>阵列
(
[id]=>6
[标题]=>第二方
[开始]=>2017-04-27
[结束]=>2017-04-29阵列
(
[0]=>xxx
[1] =>yyy
)
[颜色]=>#26B99A
[zeit]=>zzz
)
[2] =>阵列
(
[id]=>11
[标题]=>第三方
[开始]=>2017-07-30
[完]=>2017-07-31阵列
(
[0]=>xxx
[1] =>yyy
)
[颜色]=>#26B99A
[zeit]=>zzz
)
因此,我使用了一个PHP函数,通过事件标题对其进行格式化:
PHP:
[0] => Array
(
[id] => 4
[title] => Party 1
[start] => 2017-06-14
[end] => 2017-06-14
[className] => Array
(
[0] => yyy
[1] => zzz
)
[color] => #26B99A
[zeit] => xxx
)
[1] => Array
(
[id] => 6
[title] => Party 2
[start] => 2017-04-27
[end] => 2017-04-27
[className] => Array
(
[0] => xxx
[1] => yyy
)
[color] => #26B99A
[zeit] => zzz
)
[2] => Array
(
[id] => 7
[title] => Party 2
[start] => 2017-04-28
[end] => 2017-04-28
[className] => Array
(
[0] => xxx
[1] => yyy
)
[color] => #26B99A
[zeit] => zzz
)
[3] => Array
(
[id] => 9
[title] => Party 2
[start] => 2017-04-29
[end] => 2017-04-29
[className] => Array
(
[0] => xxx
[1] => yyy
)
[color] => #26B99A
[zeit] => zzz
)
[4] => Array
(
[id] => 11
[title] => Party 3
[start] => 2017-07-30
[end] => 2017-07-30
[className] => Array
(
[0] => xxx
[1] => yyy
)
[color] => #26B99A
[zeit] => zzz
)
[5] => Array
(
[id] => 13
[title] => Party 3
[start] => 2017-07-31
[end] => 2017-07-31
[className] => Array
(
[0] => xxx
[1] => yyy
)
[color] => #26B99A
[zeit] => zzz
)......
function formateEvents($event_array){
$events = array();
foreach($event_array as $event)
{
if(!isset($events[$event['title']]))
{
$events[$event['title']]['id'] = $event['id'];
$events[$event['title']]['title'] = $event['title'];
$events[$event['title']]['start'] = $event['start'];
$events[$event['title']]['end'] = $event['end'];
$events[$event['title']]['name'] = $event['title'];
$events[$event['title']]['className'] = $event['className'];
$events[$event['title']]['color'] = $event['color'];
$events[$event['title']]['zeit'] = $event['zeit'];
}else{
if(strtotime($event['start']) < strtotime($events[$event['title']]['start']))
{
$events[$event['title']]['start'] = $event['start'];
}
if(strtotime($event['end']) > strtotime($events[$event['title']]['end']))
{
$events[$event['title']]['end'] = $event['end'];
}
}
}
return array_values($events);
}
函数格式事件($event\u数组){
$events=array();
foreach($event\u数组作为$event)
{
如果(!isset($events[$event['title']]))
{
$events[$event['title']['id']=$event['id'];
$events[$event['title']['title']=$event['title'];
$events[$event['title']['start']=$event['start'];
$events[$event['title']['end']=$event['end'];
$events[$event['title']['name']=$event['title'];
$events[$event['title']['className']=$event['className'];
$events[$event['title']['color']=$event['color'];
$events[$event['title']['zeit']=$event['zeit'];
}否则{
if(strotime($event['start'])strotime($events[$event['title']]['end']))
{
$events[$event['title']['end']=$event['end'];
}
}
}
返回数组_值($events);
}
这适用于上述数据集。
但是:问题是,我也有多年前的事件数据,它们通常都有相同的标题。在这种情况下,事件持续时间为多年。我希望通过一种方式来防止这种情况,即只合并具有相同名称的数据以及连接的天数
唯一的方法,在我脑海中,就是检查这几天是否是连续的。。。如2018-01-01、2018-01-02、2018-01-03应为同一事件。。。如果中间少了一天,它应该算作另一个事件我的解决方案比我想要的要复杂得多,但它正在工作。 那么,让我解释一下 首先我按标题绘制所有事件的地图
$eventsIndexedByTitleAndEndDate = array();
foreach ($event_array as $event) {
$eventTitle = $event['title'];
$eventEnd = $event['end'];
$eventsIndexedByTitleAndEndDate[$eventTitle][$eventEnd] = $event;
}
然后我遍历这些数据以找到我想要使用的日期,然后我将这些日期映射到另一个数组中,仍然使用事件的标题作为主索引
$eventDates = array();
foreach ($eventsIndexedByTitleAndEndDate as $eventTitle => $eventIndexedByTitle) {
$datesFromIndexedTitle = (array_keys($eventIndexedByTitle));
$start = $datesFromIndexedTitle[0];
$end = $datesFromIndexedTitle[0];
foreach ($datesFromIndexedTitle as $dateFromIndexedTitle) {
$nextDayFromEnd = date('Y-m-d', strtotime("+1 day", strtotime($end)));
if ($dateFromIndexedTitle == $nextDayFromEnd) {
$end = $dateFromIndexedTitle;
} elseif ($dateFromIndexedTitle > $nextDayFromEnd) {
$eventDates[$eventTitle][] = [
'start' => $start,
'end' => $end,
];
$start = $dateFromIndexedTitle;
$end = $dateFromIndexedTitle;
}
}
$eventDates[$eventTitle][] = [
'start' => $start,
'end' => $end,
];
}
在映射完所有日期后,我使用引用运行此数组,以使用按标题索引的数组中的数据更新键,并按应更新开始/结束日期
foreach ($eventDates as $title => &$eventDate) {
foreach ($eventDate as &$eachEvent) {
$start = $eachEvent['start'];
$end = $eachEvent['end'];
$eachEvent = $eventsIndexedByTitleAndEndDate[$title][$start];
$eachEvent['start'] = $start;
$eachEvent['end'] = $end;
}
}
我相信可能有一种更简单的方法可以做到这一点,但我现在想不出一个解决方案,尽管这是一个很好的练习 我认为需要指定一个事件与另一个具有相同标题的事件的连接时间。但是有了这个集合,您可以将结果累积到另一个按标题索引的数组中,并与您拥有的日期进行比较,对每个结果进行评估。你明白我的意思吗?我知道了,但不可能概括事件持续时间。。。可以是1天到3个月。其中一些是从12月到1月,所以我也不能按年份将它们分开。我理解这一点。但您说:“我想以一种方式防止这种情况发生,即只有同名的数据以及连接的天数才能合并。”。在这个场景中,你如何决定这些天是否是相连的呢?我想到的唯一方法是检查这些天是否是连续的。。。如2018-01-01、2018-01-02、2018-01-03应为同一事件。。。如果中间少了一天,就应该算作另一个事件好的,这很有帮助。请将此信息添加到问题本身,以便每个人都能阅读。:)这和我的功能差不多如果旧事件的标题与新事件的标题相同,则问题仍然存在。:-)现在检查它。:)好。。。如果我将每个
$eachEvent
保存到一个新数组中,并在fkt结束时返回它,它将按照我的要求工作,谢谢!)只是要小心,在这种特殊情况下,如果确实有很多事件,这将严重影响性能,因此我建议在某个时候找到一种方法来更新数据库。因为这个函数(一旦数据库正确)就不再需要了。我已经在表中添加了一个新字段event\u id
,并使用这个函数相应地组合事件;-),之后,我就可以通过它的新事件id获得我想要的事件