jakewhiteley / php-sets
PHP 中类似 Java 集合数据结构的实现。集合是一个可迭代的序列化数据结构,允许严格类型存储唯一值。
Requires
- php: >=7.4
Requires (Dev)
- phpunit/phpunit: ^9.6.8
This package is auto-updated.
Last update: 2024-08-30 02:05:34 UTC
README
php-set-data-structure
Java 集合数据结构的 PHP 实现。
集合简单来说是一组可以按插入顺序迭代的唯一事物。因此,集合的一个显著特征是它不包含重复项。
实现基于 EMCA 6 JavaScript 中集合的 MDN JS 参考 MDN JS Reference。
集合需要 PHP 版本 7.4 或更高。
安装
您可以通过此页面的发布链接下载最新版本。
PHP-Sets 通过 Composer 提供,运行以下命令
composer require jakewhiteley/php-sets
然后按如下方式将库包含到您的项目中
include('vendor/autoload.php'); use PhpSets\Set;
基本用法
创建一个集合
创建集合时,您可以插入初始值或将其保持为空。
$set = new Set(1, 2, 3); $emptySet = new Set();
集合不能包含重复的值,并且值按照插入顺序存储。
// $set contains [1, 2, 3] as duplicates are not stored $set = new Set(1, 2, 1, 3, 2);
如果您有一个元素数组,您可以直接传递该数组,或者展开该数组。
$set = new Set([1, 2, 1, 3, 2]); $array = [1, 2, 1, 3, 2]; $set = new Set(...$array);
添加值
通过 add() 方法可以将任何类型的值(包括对象、数组和其他 Sets)添加到集合中。
值得注意的是,唯一性是基于 严格类型 的,因此 (string) '1' !== (int) 1 !== (float) 1.0。这也适用于集合中的对象,即使属性等相同,具有类A的对象也不等于具有类B的对象。
// create empty Set $set = new Set(); $set->add('a'); // $set => ['a'] $set->add(1); // $set => ['a', 1]
由于 Sets 实现了 ArrayAccess 接口,您也可以像标准数组一样添加值。
$set = new Set(); $set[] = 1; $set[] = 'foo'; // $set => [1, 'foo'] // You can also replace values by key, provided the new value is unique within the Set $set[0] = 2; // $set => [2, 'foo'] // If a key is not currently in the array, the value is appended to maintain insertion order $set[4] = 'foo'; // $newSet => [2, 'foo', 'foo']
删除值
您可以通过 delete() 单独删除值,或者通过 clear() 方法一次性删除所有值。
$set = new Set(1, 2, 3); $set->delete(2); // $set => [1, 3] $set->clear(); // $set => []
您也可以通过 ArrayAccess 删除方法
$set = new Set(1, 2, 3); unset($set[0]); // $set => [2, 3]
检查值是否存在
您可以通过 has($value) 方法轻松检查集合是否包含值。
与其他方法一样,这是一个 严格类型 测试。
$set = new Set('a', [1, 2], 1.0); $set->has('a'); // true $set->has([1, 2]); // true $set->has(1); // false $set->has([1, '2']); // false $set->has('foo'); // false
计算元素数量
这是通过 count 方法完成的
$set = new Set(1, 2, 3); echo $set->count(); // 3
迭代
迭代集合有多种方法
- 类似于传统 PHP 数组
- 使用
entries()返回 PHP 的ArrayIterator实例 - 使用
each()和提供的回调函数 - 使用
values(),它返回集合的传统 PHP 数组版本
作为传统数组
集合对象扩展了 ArrayObject,可以像正常数组一样迭代
$set = new Set(1, 2); foreach ($set as $val) { print($val); }
或者,如果您愿意,您也可以迭代 $set->values()。
使用 entries()
entries() 方法返回一个 ArrayIterator 对象。
$iterator = $set->entries(); while ($iterator->valid()) { echo $iterator->current(); $iterator->next(); }
使用 each($callback, ...$args)
您还可以通过提供的 可调用 方法遍历一个 Set。
回调函数将以当前项作为参数 1,并以任何其他指定的参数作为后续参数调用。
function cb($item, $parameter) { echo $item * $parameter; } $set = new Set(1, 2); $set->each('cb', 10); // prints 10 20
集合操作
并集
将第二个 Set 追加到给定的 Set 中,而不创建重复项
$a = new Set(1, 2, 3); $b = new Set(2, 3, 4); $merged = $a->union($b); print_r($merged->values()); // [1, 2, 3, 4]
差集
difference() 方法将返回一个新的 Set,其中包含原始 Set 中存在但不在另一个 Set 中的值。
这也可以称为 相对补集。
$a = new Set(1, 2, 3, 4); $b = new Set(3, 4, 5, 6); print_r($a->difference($b)->values()); // [1, 2] print_r($b->difference($a)->values()); // [5, 6]
对称差集
symmetricDifference() 方法也会返回一个新的 Set,但它与 difference 方法不同,因为它将返回两个 Set 之间的所有不同值。
$a = new Set(1, 2, 3, 4); $b = new Set(3, 4, 5, 6); print_r($a->symmetricDifference($b)->values()); // [1, 2, 5, 6]
交集
返回一个新 Set,其中包含两个集合之间共同(存在于两个集合中)的项
$a = new Set(1, 2, 3); $b = new Set(2, 3, 4); $intersect = $a->intersect($b); print_r($intersect->values()); // [2, 3]
子集
isSupersetOf 方法返回一个 bool,指示给定的 Set 是否是当前 Set 的子集。
值的顺序不重要,但子集必须只包含原始 Set 中存在的项
$a = new Set(1, 2, 3); $b = new Set(2, 3); var_Dump($b->isSupersetOf($a)); // true var_Dump($a->isSupersetOf($b)); // false
集合家族操作
如果我们有一组集合,例如 { { 1,2,3 }, { 3,4,5 } , { 3, 5, 6, 7 } },在集合论中通常称为 集合族,我们可以取该族的所有并集和交集。也就是说,( { 1, 2, 3 } 并 { 3, 4, 5 } ) 并 { 3, 5, 6, 7 },同样也适用于交集。在集合论中,使用一个大并集和交集符号来表示这个目的。
请注意,目前,这些操作是通过迭代调用上述的 union 和 intersect 方法实现的。更有效的实现是可能的,并受到欢迎。
集合族的并集
目前,集合族需要是一个包含 Set 对象的数组
$set1 = Set(1, 2, 3); $set2 = Set(3, 4, 5); $set2 = Set(5, 1, 6); $set_union = Set::familyUnion([$set1, $set2]); // [1, 2, 3, 4, 5, 6]
集合族的交集
与 familyUnion 一样,集合族需要是一个包含 Set 对象的数组
$set1 = Set(1,2,3); $set2 = Set(3,4,5); $set_family = [ $set1, $set2 ]; $set_intersection = Set::familyIntersection($set_family);
请注意,与集合论不同,取空数组的交集的结果是一个空数组。(在集合论中,空族的交集是未定义的,因为它将是 '所有集合的集合'。)
贡献
欢迎贡献和更改!只需打开一个问题或提交一个 PR 💪