【问题标题】:PHP group array by date with intervalPHP按日期分组数组,有间隔
【发布时间】:2020-10-10 18:42:10
【问题描述】:

我有这个数组

  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];
        }

【问题讨论】:

  • 你想说date] =&gt; 2020-10-07 10:49:48 [content] =&gt; 1, 2
  • 1和2元素相差1分钟,应该分组
  • 好吧抱歉,但是你重新组合 [content] => 2, 3,3 在哪里? [日期] => 2020-10-08 13:49:48 在哪里?
  • 3 元素当然应该被移除并加入到 2 中。
  • 我们需要按顺序还是按任何顺序检查。或者如果第一条记录是7:00,第二条记录是7:50,第三条记录是8:30,会发生什么情况。这些应该合并吗?

标签: php arrays


【解决方案1】:

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

数组将按日期的降序排序。最高日期设置为 $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);

$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,
  ),
) 

$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',
  ),
) 

【讨论】:

    【解决方案2】:

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

    例如,尽管未设置,但以下内容将输出 12

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

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

      $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);
    

    【讨论】:

      猜你喜欢
      • 2015-03-01
      • 2021-02-25
      • 1970-01-01
      • 2020-11-19
      • 2016-10-06
      • 2011-03-02
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多