繁体   English   中英

PHP 按时间间隔对数组进行分组

[英]PHP group array by date with interval

我有这个数组

  Array
  (
    [0] => Array
        (
            [date] => 2020-10-07 10:49:48
            [content] => 1
        )
    [1] => Array
        (
            [date] => 2020-10-08 13:49:48
            [content] => 2
        )
    [2] => Array
        (
            [date] => 2020-10-08 13:50:03
            [content] => 3
        )
  )

我想得到:

  Array
  (
    [0] => Array
        (
            [date] => 2020-10-07 10:49:48
            [content] => 1
        )
    [1] => Array
        (
            [date] => 2020-10-08 13:50:03
            [content] => 2, 3
        )
  )

如您所见,如果元素之间的日期小于小时(例如),则两个元素的内容应按较大的日期值分组。 我只是不明白如何正确地做

我明白了,但不知道为什么我在数组中有额外的元素

        foreach ($result as $key => $value) {
            foreach ($result as $key2 => $value2) {
                if (abs(strtotime($value['date_added']) - strtotime($value2['date_added'])) <= 3600 && $key != $key2) {
                    $result[$key]['content'] = $value['content'] . ',' . $value2['content'];
                    unset($result[$key2]);
                }
            }
            $merged_array[] = $result[$key];
        }

没有明确描述应该使用哪个时间差。 这里的解决方案总是计算到组中最高日期的时间差。

该数组将按日期的降序排序。 最高日期设置为 $groupDate。 使用 foreach 循环创建一个新的 $result 数组。 如果与 $groupDate 的日期差小于 $intervalHour,则累积“内容”。 在另一种情况下,设置了一个新的 $groupDate 。 最后,结果数组根据增加的日期再次排序。

$data = [
  ['date' => '2020-10-07 10:49:48', 'content' => 1],
  ['date' => '2020-10-08 13:49:48', 'content' => 2],
  ['date' => '2020-10-08 13:50:03', 'content' => 3],
  ['date' => '2020-10-08 14:50:04', 'content' => 4],
];

$intervalHour = 1.0;

usort($data,function($a,$b){return $b['date'] <=> $a['date'];});

$groupDate = date_create($data[0]['date']);
$content = $data[0]['content'];
$result = [$data[0]];
$k = 0;
foreach($data as $i => $row){
  if($i == 0) continue;
  $diff = date_create($row['date'])->diff($groupDate);
  $diffHour = $diff->days * 24 + $diff->h + $diff->i/60 + $diff->s/3600;  
  if($diffHour < $intervalHour) {
    $content = $row['content'].','.$content;
  }
  else {
    ++$k;
    $groupDate = date_create($row['date']);
    $result[$k]['date'] = $groupDate->format('Y-m-d H:i:s');
    $content = $row['content'];
  }
  $result[$k]['content'] = $content;
}

usort($result,function($a,$b){return $a['date'] <=> $b['date'];});

echo '<pre>',var_export($result);

Output $intervalHour = 1.0

array (
  0 => 
  array (
    'date' => '2020-10-07 10:49:48',
    'content' => 1,
  ),
  1 => 
  array (
    'date' => '2020-10-08 13:50:03',
    'content' => '2,3',
  ),
  2 => 
  array (
    'date' => '2020-10-08 14:50:04',
    'content' => 4,
  ),
) 

Output $intervalHour = 2.0

array (
  0 => 
  array (
    'date' => '2020-10-07 10:49:48',
    'content' => 1,
  ),
  1 => 
  array (
    'date' => '2020-10-08 14:50:04',
    'content' => '2,3,4',
  ),
) 

问题是您的unset命令不起作用。 当您在数组上使用 foreach 时,将创建并迭代该数组的副本。 如果您想迭代一个可以动态更改的实例,则需要传递一个可迭代的 object。

例如,尽管未设置,但以下将是 output 12

$x = [1, 2];

foreach ($x as $key => $value) {
    echo $value;
    unset($x[1]);
}

我认为最好的方法是使用 OOP。但是如果你只想使用 forloops 和 arrays,可以这样做:

  $usedKeys = [];
  $dateContent  =[];

  foreach ($result as $key => $value) {
      if (in_array($key, $usedKeys)) {
          continue;
      }
      $usedKeys[] = $key;
      $dateContent[$key]['content'] = [$value['content']];
      foreach ($result as $key2 => $value2) {
          if (in_array($key2, $usedKeys)) {
              continue;
          }

          if (abs(strtotime($value['date']) - strtotime($value2['date'])) <= 3600 && $key != $key2) {
              $dateContent[$key]['content'][] = $value2['content'];
              $usedKeys[] = $key2;
          }
      }
  }

  $dateContent = array_map(function ($value) {
      return implode(',', $value['content']);
  }, $dateContent);

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM