cocur/chain

一致的链式数组操作

v0.9.0 2020-07-19 15:36 UTC

README

Chain 为您提供了在 PHP 中一致且可链式操作的数组方式。

Build Status Windows Build status Scrutinizer Code Quality Code Coverage

由欧洲维也纳的 Florian Eckerstorfer 制作。

动机

让我们坦诚。在 PHP 中操作数组是一个混乱的过程。首先,你必须将大多数(但不是全部)函数前缀为 array_,参数顺序不一致。例如,array_map() 预期回调作为第一个参数,数组作为第二个,但 array_filter() 预期数组作为第一个,回调作为第二个。你还必须将函数调用包围在数组周围,生成的代码看起来不美观,难以阅读和理解。

$arr = array_filter(
    array_map(
        function ($v) { return rand(0, $v); },
        array_fill(0, 10, 20)
    ),
    function ($v) { return $v & 1; }
);

Chain 将数组包装成对象,并为你提供可链式接口。

$chain = Chain::fill(0, 10, 20)
    ->map(function ($v) { return rand(0, $v); })
    ->filter(function ($v) { return $v & 1; });

看看以下代码。你需要多长时间才能理解它?

echo array_sum(array_intersect(
    array_diff([1, 2, 3, 4, 5], [0, 1, 9]),
    array_filter([2, 3, 4], function ($v) { return !($v & 1); })
));

再看看这个?

echo Chain::create([1, 2, 3, 4, 5])
    ->diff([0, 1, 9])
    ->intersect(Chain::create([2, 3, 4])->filter(function ($v) { return !($v & 1); }))
    ->sum();

提示:它计算两个数组的差值,与过滤后的数组交集,并求和。

安装

您可以使用 Composer 安装 Chain。

$ composer require cocur/chain

用法

Chain 允许您创建、操作和访问数组。

数组创建

您可以通过将数组传递给构造函数来创建一个 Chain。

$chain = new Chain([1, 2, 3]);

或者使用方便的静态方法

$chain = Chain::create([1, 2, 3]);

此外,Chain 还可以通过静态 fill() 方法创建,它是对 array_fill() 函数的包装。

$chain = Chain::fill(0, 10, 'foo');

还有一个方法,::createFromString(),它可以从字符串创建 Chain。除了字符串外,您还需要提供一个分隔符,该分隔符用于分割字符串。如果传递了 regexp 选项,则分隔符必须是一个正则表达式。

Chain::createFromString(',', '1,2,3')->array;                               // -> [1, 2, 3]
Chain::createFromString('/,|.|;/', '1,2.3;4,5', ['regexp' => true])->array; // -> [1, 2, 3, 4, 5]

数组操作

Chains 的操作方法操作底层数组并返回对象,即它们可以被链式调用。大多数方法都是对应 array_ 函数的简单包装。

在下面的示例中,使用 ->map() 将每个元素乘以 3,然后过滤数组以仅包含奇数元素。

$chain = (new Chain([1, 2, 3]))
    ->map(function ($v) { return $v*3; })
    ->filter(function ($v) { return $v & 1; });
$chain->array; // -> [3, 9]

当一个方法接受一个数组(->diff()->intersect())时,您也可以传递另一个 Chain 实例而不是数组。

数组操作方法列表

所有这些方法都会操作数组,但不是所有方法都返回 Cocur\Chain\Chain 的实例。例如,->shift() 从数组中移除第一个元素并返回它。

  • ->changeKeyCase()
  • ->combine(array|Chain, array|Chain)
  • ->count()
  • ->diff(array|Chain)
  • ->filter(callable)
  • ->find(callable)
  • ->flatMap(callable)
  • ->flip()
  • ->intersect(array|Chain)
  • ->intersectAssoc(array|Chain)
  • ->intersectKey(array|Chain)
  • ->keys()
  • ->map(callable)
  • ->merge(array|Chain)
  • ->pad(int, mixed)
  • ->pop()
  • ->product()
  • ->push(mixed)
  • ->reduce(callable[, int])
  • ->reverse([bool])
  • ->search(mixed[, bool])
  • ->shift()
  • ->shuffle()
  • ->sort(sortFlags)
  • ->sortKeys(sortFlags)
  • ->splice(offset[, length[, replacement]])
  • ->sum()
  • ->unique()
  • ->unshift(mixed)
  • ->values()

数组访问

最重要的是,您可以访问底层数组,使用公共的 array 属性。

$chain = new Chain([1, 2, 3]);
$chain->array; // -> [1, 2, 3]

Chain 实现了 Traversable 接口。

$chain = new Chain([1, 2, 3]);
foreach ($chain as $key => $value) {
  // ...
}

它还实现了 ArrayAccess 接口,允许像在任何普通数组中一样访问元素。

$chain = new Chain();
$chain['foo'] = 'bar';
if (isset($chain['foo'])) {
    echo $chain['foo'];
    unset($chain['foo']);
}

此外,Chain 包含了一些方法来访问数组的属性。与操作方法不同,这些方法返回一个值,而不是 Chain 对象的引用。也就是说,数组访问方法是不可链式的。

$chain = new Chain([1, 2, 3]);
$chain->count(); // -> 3
$chain->sum();   // -> 6
$chain->first(); // -> 1
$chain->last();  // -> 3

$chain->reduce(function ($current, $value) {
    return $current * $value;
}, 1); // -> 6

数组访问方法列表

  • ->count()
  • ->countValues()
  • ->every(callable)
  • ->first()
  • ->includes(mixed[, array])
  • ->join([$glue])
  • ->last()
  • ->reduce()
  • ->some()
  • ->sum()

作者

Chain 由 Florian Eckerstorfer (Twitter) 在欧洲的维也纳开发。

Chain 是 Cocur 的项目。您可以在 Twitter 上联系我们:@cocurco

支持

如果您需要支持,您可以在 Twitter 上提问(好吧,只有当您的问题简短时),或者您可以在 Gitter 上加入我们的聊天。

Gitter

如果您想支持 Chain 的开发,您可以 寄给我一两个欧元

变更日志

版本 0.9.0(2020年7月19日)

  • #42 重构以支持强类型(由 nreynis 实现)
  • #45 使用 self 返回类型(由 nreynis 实现)
  • #46 修复 splice 和 replace 的错误(由 nreynis 实现)
  • #47 在 createFromString 中处理无效的模式(由 nreynis 实现)
  • #49 移动静态工厂填充方法(由 nreynis 实现)
  • #50 添加 includes (in_array)(由 nreynis 实现)
  • #51 添加 every(由 nreynis 实现)
  • #52 添加 some(由 nreynis 实现)

版本 0.8.0(2019年9月12日)

  • #40 更新工具和依赖项,将最低 PHP 版本设置为 7.2
  • #37 添加缺失的特质 \Cocur\Chain\Chain(由 nreynis 实现)
  • #41 添加 ➞ flatMap()(由 nreynis 实现)

版本 0.7.0(2018年11月11日)

版本 0.6.0(2018年4月5日)

版本 0.5.0(2017年12月4日)

版本 0.4.1(2017年12月4日)

  • Find 链接添加到 Cocur\Chain\Chain

版本 0.4.0(2017年9月22日)

  • #17 添加 Find 链接(由 gries 提供)

版本 0.3.0(2017年9月7日)

  • #12 恢复构造函数(由 sanmai 提供)
  • 将 first() 和 last() 方法移动到 traits 中
  • 添加额外的链接(CountValuesKeyExistsSplice
  • 更新 Merge 链接

版本 0.2.0(2015年11月6日)

  • #11 添加 Cocur\Chain\Chain::createFromString() 以从字符串创建链(由 florianeckerstorfer 提供)
  • #10Cocur\Chain\AbstractChain 添加方法以检索链的第一个和最后一个元素(由 florianeckerstorfer 提供)
  • #9 Cocur\Chain\Chain 现在是可计数的

版本 0.1.0(2015年11月6日)

  • 初始发布

许可

MIT 许可证适用于 Chain。有关完整的版权和许可信息,请参阅与源代码一起分发的 LICENSE 文件。