raigu/ordered-lists-sync

用于通过最小插入和删除操作同步有序数据的库。

v0.3.0 2021-12-03 06:04 UTC

This package is auto-updated.

Last update: 2024-09-11 23:13:45 UTC


README

Latest Stable Version build codecov Scrutinizer Code Quality License: MIT Dependents

用于通过最小插入和删除操作同步有序数据的库。

适用于大型数据集。适合与外部源同步内部数据。见演示

兼容性

  • PHP 7.4, 8.0, 8.1, 8.2, 8.3

安装

$ composer require raigu/ordered-lists-sync

使用

\Raigu\OrderedListsSynchronization\Synchronization比较源列表和目标列表。它检测源相对于目标中添加或删除的元素,并调用相应的回调。

源和目标必须是Iterator类型。

$synchronization = new \Raigu\OrderedListsSynchronization\Synchronization();
$synchronization(
    $source = new ArrayIterator(['A', 'B', 'D']), 
    $target = new ArrayIterator(['B', 'C', 'D']),
    $add = function ($element) { echo "ADD: {$element}\n"; },
    $remove = function ($element) { echo "REMOVE: {$element}\n"; }
);

输出

ADD: A
REMOVE: C

用例

具有演示代码的示例用例

设计

\Raigu\OrderedListsSynchronization\Synchronization只有一个目的。因此,它被设计成一个函数实例,不暴露任何方法。它是一个对象,因为它允许在将来扩展它(例如添加日志)。

使用Iterator类型作为源和目标有几个优点。

首先,您可以创建自己的迭代器作为独立的组件,这更容易开发和测试。

其次,可以解决更复杂的问题。特别是在存在内存限制的情况下。
您可以创建源或目标作为生成器,实现IterateIteratorAggregate接口,或使用标准PHP库(SPL)迭代器

第三,它允许创建在构造函数中不做任何工作的组件。这在使用依赖注入或声明式编程时很方便。

开发

设置

$ git clone git@github.com:raigu/ordered-lists-sync.git
$ cd ordered-lists-sync
$ composer install

测试

$ composer test
$ composer coverage

算法

算法的工作方式类似于我们使用字典。如果所有单词都是有序的,那么我们就知道某个单词应该在哪里。如果我们有两个字典,并从开头逐个单词比较它们,那么我们可以检测到添加或删除的单词。

示例(V表示迭代器的当前位置)

        V
Source: A, B, D
        V
Target: B, C, D

A < B => 如果源在目标之前,这意味着目标中缺少值。如果目标中有一个A,那么它应该在B之前。但它不在那里。因此,它是缺失的,应该被添加。添加A并移动源光标

           V
Source: A, B, D
        V
Target: B, C, D

B = B => 如果源和目标相等,则它们已同步。移动两个光标。

              V
Source: A, B, D
           V
Target: B, C, D

D > C => 如果源在目标之后,这意味着源中已经从源中删除了值。因此,删除C并将光标向前移动

              V
Source: A, B, D
              V
Target: B, C, D

D = D => 它们已经同步。移动两个光标。