micoli / multitude
Requires
- php: >=8.1
- loophp/collection: ^7.1
Requires (Dev)
- friendsofphp/php-cs-fixer: ^3.16
- phan/phan: ^5.4
- php-coveralls/php-coveralls: ^0.1.0
- phpdocumentor/reflection-docblock: ^5.3
- phpstan/phpstan: ^1.10
- phpunit/phpunit: ^10.0
- ramsey/uuid: ^4.7
- symfony/var-dumper: ^6.2
- vimeo/psalm: ^5.9
README
PHP 集合库。
提供两种类型的集合
- 集合(
MutableSet
和ImmutableSet
),是唯一值序列。值可以是任何类型。 - 映射(
MutableMap
和ImmutableMap
),是键值对的顺序集合。键可以是任何类型,但必须是唯一的。值可以是任何类型。
在 ImmutableSet
和 ImmutableMap
中,如果方法更改内部值的内容,则返回相同类型的新实例。相反,在 MutableSet
和 MutableMap
中,相同的方法会更改内部值。
方法尽可能流畅。
感谢 https://github.com/BenMorel 提供该库中使用的核心思想,这是其初始版本的完整重写。
安装
此库可以通过 Composer 安装
composer require micoli/multitude
要求
此库需要 PHP 8.0 或更高版本。
项目状态
虽然此库仍在开发中,但它仍处于早期开发状态。它遵循 semver 版本标记。
快速入门
构造函数仅为静态
new MutableSet(['a','b','c'])
new MutableMap([2=>'a',3=>'b',4=>'c'])
new MutableMap([[2,'a'],['2','aa'],[3,'b'],['3','bb'],[4,'c'])
如果您需要为映射的键提供强类型,则可以使用 fromTuples 构造函数,例如 '2'
键与 2
不同。
接受 bool $throw
参数的方法如果 $throw == true
则会触发异常,如果 $throw == false
则会静默失败。
使用关联数组的示例
public function testItShouldFullyWorkWithAssociativeArray(): void { /** @var ImmutableMap<string, array{value:int,tags:list<string>}> $map */ $map = new ImmutableMap([ ['library', ['value' => 10, 'tags' => ['tag1']]], ['projects', ['value' => 5, 'tags' => ['tag2']]], ['gist', ['value' => 7, 'tags' => ['tag1', 'tag2']]], ['repository', ['value' => 7, 'tags' => ['tag3']]], ]); $totalSum = $map ->filter(fn (array $project, mixed $category): bool => array_search('tag1', $project['tags']) !== false) ->reduce(fn (int $sum, mixed $project, mixed $category): int => $sum + $project['value'], 0); self::assertSame($totalSum, 17); self::assertCount(4, $map); }
完全类型化的不可变映射的示例
文件: Project.php
<?php declare(strict_types=1); namespace Micoli\Multitude\Tests\Fixtures; class Project { public function __construct( public readonly int $value, public readonly Tags $tags, ) { } }
文件: Tags
<?php declare(strict_types=1); namespace Micoli\Multitude\Tests\Fixtures; use Micoli\Multitude\Set\ImmutableSet; /** * @extends ImmutableSet<string> */ class Tags extends ImmutableSet { }
文件: Projects
<?php declare(strict_types=1); namespace Micoli\Multitude\Tests\Fixtures; use Micoli\Multitude\Map\ImmutableMap; /** * @extends ImmutableMap<string, Project> */ class Projects extends ImmutableMap { /** * Add or replace a value in the map */ public function improvedSet(string $newKey, Project $newValue): static { // do specific stuff, like logging or ther return $this->set($newKey, $newValue); } }
public function testItShouldFullyWorkWithObjects(): void { $map = new Projects([ ['library', new Project(10, new Tags(['tag1']))], ['projects', new Project(5, new Tags(['tag2']))], ['gist', new Project(7, new Tags(['tag1', 'tag2']))], ['repository', new Project(7, new Tags(['tag3']))], ]); $totalSum = $map ->filter(fn (Project $project, mixed $category): bool => $project->tags->hasValue('tag1')) ->reduce(fn (int $sum, Project $project, mixed $category): int => $sum + $project->value, 0); self::assertInstanceOf( Projects::class, $map->filter(fn (Project $project, mixed $category): bool => true), ); self::assertSame($totalSum, 17); self::assertCount(4, $map); $newMap = $map->improvedSet('NewType', new Project(10, new Tags(['tag4']))); self::assertCount(5, $newMap); }
可用的动词
动词偶合
AbstractSet
- __construct
- append
- apply
- count
- filter
- first
- forEach
- get
- getIterator
- hasIndex
- hasValue
- indexDiff
- indexIntersect
- isEmpty
- keys
- last
- map
- reduce
- remove
- slice
- sort
- toArray
- valueDiff
- valueIntersect
- values
AbstractMap
- __construct
- apply
- count
- filter
- first
- forEach
- fromIterable
- get
- getIterator
- getTuples
- hasKey
- hasValue
- isEmpty
- keyDiff
- keyIntersect
- keys
- last
- map
- offsetExists
- offsetGet
- offsetSet
- offsetUnset
- reduce
- removeKey
- removeValue
- set
- slice
- sort
- toArray
- valueDiff
- valueIntersect
- values
AbstractSet
AbstractSet::__construct
public function __construct(iterable $values = [])
AbstractSet::append
public function append(mixed $newValue, bool $throw = true): static
在集合末尾添加一个值
AbstractSet::apply
public function apply(callable $callable): static
通过将回调函数应用于当前实例来替换所有值
AbstractSet::count
public function count(): int
返回集合中的项目数量
AbstractSet::filter
public function filter(callable $callable): static
使用回调函数过滤集合
AbstractSet::first
public function first(bool $throw = true): mixed
返回集合中的第一个值
AbstractSet::forEach
public function forEach(callable $callable): static
对集合的值应用回调函数
回调函数接收 $value
和 $index
AbstractSet::get
public function get(int $index, mixed $defaultValue = null): mixed
通过索引返回集合中的值
AbstractSet::getIterator
public function getIterator(): Traversable
返回值的迭代器
AbstractSet::hasIndex
public function hasIndex(int $index): bool
返回集合是否包含指定的索引
AbstractSet::hasValue
public function hasValue(mixed $searchedValue): bool
返回集合是否包含指定的值
AbstractSet::indexDiff
public function indexDiff(AbstractSet $compared): static
返回一个集合,其键不在参数集合中
AbstractSet::indexIntersect
public function indexIntersect(AbstractSet $compared): static
返回一个映射,其键在参数映射中
AbstractSet::isEmpty
public function isEmpty(): bool
返回集合是否为空
AbstractSet::keys
public function keys(): Generator
返回键的迭代器
AbstractSet::last
public function last(bool $throw = true): mixed
返回集合中的最新值
AbstractSet::map
public function map(callable $callable)
对值应用回调函数,保留键
回调函数接收 $value
和 $index
AbstractSet::reduce
public function reduce(callable $callable, mixed $accumulator): mixed
使用回调函数迭代地将集合缩减为一个值
回调函数接收 $accumulator
,$value
和 $index
AbstractSet::remove
public function remove(mixed $searchedValue, bool $throw = true): static
从集合中移除一个值
AbstractSet::slice
public function slice(int $offset, ?int $length = null): static
提取集合的一部分
AbstractSet::sort
public function sort(callable $callable): static
使用回调函数对映射进行排序
回调函数为 callable (TValue, TValue, int, int): int
必须返回 -1,0,1 作为比较运算符
AbstractSet::toArray
public function toArray(): array
返回表示值的数组
AbstractSet::valueDiff
public function valueDiff(AbstractSet $compared): static
返回一个集合,其值不在参数集合中
AbstractSet::valueIntersect
public function valueIntersect(AbstractSet $compared): static
返回一个集合,其值在参数集合中
AbstractSet::values
公共函数 values(): 生成器
返回值的迭代器
AbstractMap
AbstractMap::__construct
公共函数 __construct(array $tuples = [])
AbstractMap::apply
public function apply(callable $callable): static
通过将回调函数应用于当前实例来替换所有值
AbstractMap::count
public function count(): int
返回 map 中的项目数量
AbstractMap::filter
public function filter(callable $callable): static
使用回调函数过滤 map
AbstractMap::first
public function first(bool $throw = true): mixed
返回 map 中的第一个值
AbstractMap::forEach
public function forEach(callable $callable): static
对集合的值应用回调函数
AbstractMap::fromIterable
公共静态函数 fromIterable(iterable $values): 静态
从一个数组返回一个新实例
AbstractMap::get
公共函数 get(mixed $searchedKey, mixed $defaultValue = null): mixed
通过索引返回 map 中的值
AbstractMap::getIterator
public function getIterator(): Traversable
返回按键值排序的值迭代器
AbstractMap::getTuples
公共函数 getTuples(): array
AbstractMap::hasKey
公共函数 hasKey(mixed $searchedKey): bool
返回 map 是否包含特定键
AbstractMap::hasValue
public function hasValue(mixed $searchedValue): bool
返回 map 是否包含特定值
AbstractMap::isEmpty
public function isEmpty(): bool
返回 map 是否为空
AbstractMap::keyDiff
公共函数 keyDiff(AbstractMap $compared): 静态
返回一个 map,其中所有项的键不在参数 map 中
AbstractMap::keyIntersect
公共函数 keyIntersect(AbstractMap $compared): 静态
返回一个映射,其键在参数映射中
AbstractMap::keys
public function keys(): Generator
返回键的迭代器
AbstractMap::last
public function last(bool $throw = true): mixed
返回 map 中的最新值
AbstractMap::map
public function map(callable $callable)
对值应用回调函数,保留键
AbstractMap::offsetExists
公共函数 offsetExists(mixed $offset): bool
AbstractMap::offsetGet
公共函数 offsetGet(mixed $offset): mixed
AbstractMap::offsetSet
公共函数 offsetSet(mixed $offset, mixed $value): void
AbstractMap::offsetUnset
公共函数 offsetUnset(mixed $offset): void
AbstractMap::reduce
public function reduce(callable $callable, mixed $accumulator): mixed
迭代地使用回调函数将 Map 简化为单个值
回调接收 $accumulator
、$value
和 $key
AbstractMap::removeKey
公共函数 removeKey(mixed $searchedKey): 静态
通过键移除 map 中的值
AbstractMap::removeValue
公开函数 removeValue(mixed $searchedValue): static
通过值在映射中移除一个值
AbstractMap::set
公开函数 set(mixed $newKey, mixed $newValue): static
向映射中添加或替换一个值
AbstractMap::slice
public function slice(int $offset, ?int $length = null): static
提取映射的一个片段
AbstractMap::sort
public function sort(callable $callable): static
使用回调函数对映射进行排序
回调函数为 callable(TValue, TValue, TKey, TKey, int, int): int
必须返回 -1,0,1 作为比较运算符
AbstractMap::toArray
public function toArray(): array
返回表示值的数组
AbstractMap::valueDiff
公开函数 valueDiff(AbstractMap $compared): static
返回一个包含所有值不在参数映射中的项的映射
AbstractMap::valueIntersect
公开函数 valueIntersect(AbstractMap $compared): static
返回一个包含所有值在参数映射中的项的映射
AbstractMap::values
公共函数 values(): 生成器
返回值的迭代器