short-edition/interval

处理间隔的库

1.3.3 2020-08-06 17:22 UTC

README

Travis Coverage Status Codacy Badge Total Downloads Latest Stable Version

间隔

此库提供了一些处理间隔的工具。例如,您可以计算两个间隔的并集或交集。

使用场景

  • 可用性计算。
  • 调度/日历/计划。
  • 具有开放/闭合边界的数学间隔计算
  • 等等

特性

  • 它计算两个间隔之间的某些操作:并集、交集和排除。
  • 它计算两个间隔集合之间的某些操作:目前只支持排除。
  • 它处理多种类型的边界:浮点数、\DateTime 和整数。
  • 它处理 无穷大 类型的边界。
  • 能够 组合 无穷大与 \DateTime 和其他类型。
  • 过滤、排序、映射。
  • 不可变性。
  • 链式操作。

质量

  • 代码覆盖率 Coverage Status
  • 突变测试:代码覆盖率超过 90%
  • 关注性能和内存使用
  • PSR1/PSR2,代码异味

安装

composer require kirouane/interval

基本用法

假设一个间隔 [20, 40]。我们实例化一个新的 Interval 对象。

$interval = new Interval(20, 40);// [20, 40];

$interval = Interval::create('[20,40]');// [20, 40];

我们可以执行一些操作,如

  • 交集
echo $interval->intersect(new Interval(30, 60)); // [30, 40];
  • 并集
echo $interval->union(new Interval(30, 60)); // {[20, 60]};

echo $interval->union(new Interval(60, 100)); // {[20, 40], [60, 100]};
  • 排除
echo $interval->exclude(new Interval(30, 60)); // {[20, 30[};

echo $interval->exclude(new Interval(30, 35)); // {[20, 30[, ]35, 40]};

我们还可以比较两个间隔

  • 重叠测试
echo $interval->overlaps(new Interval(30, 60)); // true;
  • 包含测试
echo $interval->includes(new Interval(30, 60)); // false;

使用 DateTimeInterface 作为边界

$interval = new Interval(new \DateTime('2016-01-01'), new \DateTime('2016-01-10'));
// [2016-01-01T00:00:00+01:00, 2016-01-10T00:00:00+01:00];
  • 并集
echo $interval->union(Interval::create('[2016-01-10, 2016-01-15]')); 
// {[2016-01-01T00:00:00+01:00, 2016-01-15T00:00:00+01:00]};

使用无穷大作为边界

$interval = new Interval(-INF, INF);// ]-∞, +∞[;
  • 排除
echo $interval->exclude(Interval::create('[2016-01-10, 2016-01-15]')); 
// {]-∞, 2016-01-10T00:00:00+01:00[, ]2016-01-15T00:00:00+01:00, +∞[};

对间隔集合(数组)的操作

$intervals = Intervals::create(['[0,5]', '[8,12]']);// {[0, 5], [8, 12]};
  • 排除
echo $intervals->exclude(Intervals::create(['[3,10]'])); // {[0, 3[, ]10, 12]};

链式操作

$result = Interval
    ::create('[10, 20]')
    ->intersect(new Interval(11, 30))
    ->union(new Interval(15, INF))
    ->exclude(Intervals::create(['[18, 20]', '[25, 30]', '[32, 35]', '[12, 13]']))
    ->sort(function (Interval $first, Interval $second) {
        return $first->getStart()->getValue() <=> $second->getStart()->getValue();
    })
    ->map(function (Interval $interval) {
        return new Interval(
            $interval->getStart()->getValue() ** 2,
            $interval->getEnd()->getValue() ** 2
        );
    })
    ->filter(function (Interval $interval) {
        return $interval->getEnd()->getValue() > 170;
    }); 

// {[169, 324], [400, 625], [900, 1024], [1225, +∞[};
    
echo $result;    

高级用法

您可以使用 开放 边界创建间隔

$result = Intervals
    ::create([']10, +INF['])
    ->exclude(Intervals::create([']18, 20]', ']25, 30[', '[32, 35]', ']12, 13]']));

// {]10, 12], ]13, 18], ]20, 25], [30, 32[, ]35, +∞[}

贡献

非常欢迎您为此库做出贡献!

  • 克隆 git clone https://github.com/Kirouane/interval.git

  • 安装 composer installmake install(使用 docker 和 docker-compose)

  • 测试 vendor/bin/phpunit

  • 构建 vendor/bin/grumphp run