梦游者/集合

无依赖的集合实现。

5.5.0 2024-06-15 23:00 UTC

README

GitHub Actions Build Status Issues License PHP Version Current Version

梦游者集合提供了一种创建自定义集合和伪集合的框架。它已完全重新设计,从先前版本到一系列行为(特性)和一些围绕功能分组的基本接口。

基本的 "集合" 是一个扩展了 ArrayAccess、IteratorAggregate 和 Countable 的接口;并添加了 Arrayable 和 Jsonable 作为常见要求。然后基本方法包括:

public function all(): array;
public function contains($value): bool;
public function doesNotContain($value): bool;
public function each(callable $callback);
public function filter($criteria = null);
public function first();
public function get($key, $default = null);
public function has(...$key): bool;
public function keys($search = null);
public function last();
public function map(callable $callable);
public function value($key, $default = null);
public function values();

从这些,通过接口和特性添加了附加功能 - 或者实现自己的。目标是允许一系列小、可重用、经过良好测试的函数,可以将它们组合起来以提供所需的函数,而不是一个单一的大集合类,它什么都能做。

当然,开箱即用,还包括了几个标准实现。

这受到了 Doctrine ArrayCollection 的极大启发,当然还有 Laravel Collection,以及 Lithium 框架、ez Components、CakePHP 等想法。

如果您发现缺少某些内容或有其他方法的建议,请提交 PR 或工单!使用特性系统添加函数很容易,如果您认为分组需要改进,请提出更好的名称!

变更历史

需求

  • PHP 8.0+
  • ext-json 用于 JSON 导出

安装

使用 composer 安装,或从 github.com 检出/拉取文件。

  • composer require somnambulist/collection

贡献

欢迎贡献!无论是文档改进、新方法还是错误修复。在所有情况下,请从存储库分叉,创建一个分支,然后提交 PR - 常规 GitHub 流程。

请考虑以下事项

  • PHP 的最低版本为 8.0
  • 特性不应指定返回类型,但必须包含 docblock 返回类型
  • 集合的返回类型必须是 static 以允许运行时解析
  • 所有特性方法都必须有 docblock - 这些将被转换为文档
  • 如果特性从其他地方使用代码,应尽可能进行归属
  • 考虑操作类型以及它是否可以在 Set 或 Frozen 集合中工作
  • 应包含测试

请记住,集合可以是 Set 或 Frozen,因此通常需要在处理值后创建新的集合。请参阅当前实现以获取示例。

内置集合

有几种类型的集合,它们都实现了 Collection 接口,具有不同的功能级别

  • SimpleCollection - 一个非常基本的、类似于 Doctrine ArrayCollection 风格的集合
  • MutableCollection - 更像 Laravel Collection,支持点符号访问
  • FrozenCollection - 更像 Symfony Frozen ParameterBag,但更多,支持点符号
  • MutableSet - 一个不允许重复值的伪集合,但允许字符串键。

没有冻结集合,但如果你冻结了一个 MutableSet,你就有了一个 FrozenSet。

用法

使用数组或其他项目集合实例化

$collection = MutableCollection::collect($items);
$collection->map()->filter()...

冻结集合的更改

$locked = $collection->freeze();

// raises exception
$locked->shift();

使用自定义不可变集合类

MutableCollection::setFreezeableClass();
$locked = $collection->freeze();

// raises exception
$locked->shift();

点访问

点访问可在以下操作中提供

  • has*
  • get
  • 提取
  • 聚合函数

例如:users.*.name将从所有用户键空间的元素中获取名称。点访问可以调用到

  • 数组
  • 集合
  • 公共对象属性
  • 对象返回方法,例如:name将被转换为name()
  • 对象get方法,例如:name将被转换为getName()

如果键名使用蛇形命名法,例如:user_address,则在方法访问检查时将转换为UserAddress。

可以使用get()提供一个默认值,如果指定的键不存在,则使用该默认值。默认值可以是闭包。注意:这将对所有元素进行调用,例如:具有默认值返回0users.*.age,对于所有没有年龄的用户将返回0。

键遍历是通过一个独立的类实现的,允许它在其他类中重用。这个功能是基于Laravel的data_get()Arr::pluck(),修改为支持从对象中提取时的获取方法和默认处理。

代理助手

在v4中,对运行/映射代理进行了扩展,用于在集合上执行操作。现在可以绑定更多的代理到可以在运行时访问的虚拟属性。这允许有额外的自定义行为或在集合中创建小型的领域特定语言。

建议在添加额外的代理选项时,在集合的子类中这样做,以便可以使用类文档块中的@property-read声明来记录选项。默认情况下,runmap在内置集合中预先绑定,但在必要时可以覆盖它们。

代理在访问时是延迟实例化的,因此应该对性能影响最小。对于大多数情况,代理通过全限定类名映射到一个别名,但对于更复杂的构造可以使用闭包。

可以通过以下方式调用代理

  • $collection->proxy(<别名>)->someMethod()
  • $collection-><别名>->someMethod()

例如:在具有此方法的对象集合上运行setDateTo()方法

  • $collection->run->setDateTo(new DateTime())
  • $collection->proxy('run')->setDateTo(new DateTime())

方法索引

集合行为文档是从源代码生成的,并在docs文件夹中可用。

工厂方法

在集合类中

  • collect()静态创建一个新的集合
  • create()静态创建一个新的集合

作为FactoryUtils中的助手

  • createFromIniString()从ini风格的字符串创建一个集合
  • createFromString()将编码的字符串分割成一个集合
  • createFromUrl()给定一个URL,使用parse_url()返回一个集合
  • createFromUrlQuery()使用parse_str()将URL查询字符串转换为集合
  • createWithNestedArrayFromKey将类似于user.addresses.home的键转换为嵌套集合
  • explode()将字符串拆分到一个集合中

按组划分的方法

魔术方法和PHP接口方法

  • getIterator
  • offsetGet
  • offsetExists
  • offsetSet
  • offsetUnset
  • __get
  • __isset
  • __set
  • __set_state
  • __unset