PHP - 从开始和结束时间戳集构建时间轴数据的最佳方法

时间:2017-05-15 16:35:44

标签: php algorithm sorting

我有一系列数组项,如下所示:

[{
    "id": 1,
    "start": "2017-04-05 16:27:08",
    "end": "2017-04-05 16:30:45"
}, {
    "id": 2,
    "start": "2017-04-05 16:15:08",
    "end": "2017-04-05 16:22:45"
}, {
    "id": 2,
    "start": "2017-04-05 16:10:08",
    "end": "2017-04-05 16:17:45"
}]

我想从这个数组构建一个数组,这个数组允许我显示我的项目的时间轴。时间轴在Y轴上始终有一条线。如果原始数组中有多个项目彼此重叠,则这些项目将合并为一个项目。

对于上面的数组,我要查找的结果数组如下所示:

[{
    "start": "2017-04-05 16:10:08",
    "end": "2017-04-05 16:22:45"
}, {
    "start": "2017-04-05 16:27:08",
    "end": "2017-04-05 16:30:45"
}]

最好的方法是什么?

2 个答案:

答案 0 :(得分:1)

这非常复杂。如果它的少量项目然后用PHP或Javascript来编写数据就足够了,但是如果它有大量的项目,那么在数据库中进行这样就可以了。

关于少量项目 - 您只需要

  • 按开始排序
  • 遍历数组,并为每个项目
    • 遍历数组中的后续条目以查看它们是否相交 - 以及它们是否合并它们

这具有O(n ^ 2)的顺序,其不能很好地扩展。

在具有传统索引的数据库中执行此操作不会有太大帮助 - 这些对于通过(例如)

过滤的查询非常有用
SELECT *
FROM table t
WHERE t.value BETWEEN $a_literal AND $another_literal

但是这些指数不适用于

SELECT *
FROM table t
WHERE $a_literal BETWEEN t.start and t.end

除非每个记录中定义的范围远小于表中保存的数据的总范围。

此时解决方案是使用地理空间索引并将时间间隔映射到二维空间中的区域(因为MySQL不支持一维地理空间索引)。

因此,可以使用订单O(nlog(n))实现问题的完整解决方案,但是我已经在这里充分考虑了这个问题。

DBMS擅长快速处理批量操作 - 因此最初描述的强力方法在数据库中运行速度比在PHP / Javascript中快 -​​ 但计算资源在PHP和Javascript中更容易扩展。

答案 1 :(得分:0)

这里我们使用简单的foreach循环来实现所需的输出。另外我们正在检查timestamp并比较它们

Try this code snippet here

<?php
ini_set('display_errors', 1);
$json='[{
    "id": 1,
    "start": "2017-04-05 16:27:08",
    "end": "2017-04-05 16:30:45"
}, {
    "id": 2,
    "start": "2017-04-05 16:15:08",
    "end": "2017-04-05 16:22:45"
}, {
    "id": 2,
    "start": "2017-04-05 16:10:08",
    "end": "2017-04-05 16:17:45"
}]';
$array=  json_decode($json,true);
$result=array();
foreach($array as $key => $value)
{
    if(isset($result[$value["id"]]))
    {
        //checking which start-time is less
        if(strtotime($result[$value["id"]]["start"]) > strtotime($value["start"]))
        {
            $result[$value["id"]]["start"]=$value["start"];
        }
        //checking which end-time is greater
        if(strtotime($result[$value["id"]]["end"]) < strtotime($value["end"]))
        {
            $result[$value["id"]]["start"]=$value["end"];
        }
    }
    else
    {
        $id=$value["id"];
        unset($value["id"]);
        $result[$id]=$value;
    }
}
print_r($result);

<强>输出:

Array
(
    [1] => Array
        (
            [start] => 2017-04-05 16:27:08
            [end] => 2017-04-05 16:30:45
        )

    [2] => Array
        (
            [start] => 2017-04-05 16:10:08
            [end] => 2017-04-05 16:22:45
        )

)