dbrans/stream-pipeline

基于流的管道模式实现

2.4.0 2023-03-12 23:53 UTC

This package is auto-updated.

Last update: 2024-09-13 03:19:08 UTC


README

Build Status

Stream Pipeline

基于流的管道模式实现。

管道模式使用有序阶段来处理一系列输入值。每个实现的任务都由管道的一个阶段表示。你可以将管道类比为工厂中的装配线,其中装配线上的每个物品都按阶段构建。

工作原理

Stream pipeline 允许你从编写表达式

$input = [' B1 ', ' B2', 'a1 ', ' a2 ', 'a3', ' b1', ' b2', 'b3'];
$elements = [];

foreach ($input as $e) {
    $elem = strtoupper(trim($e));

    if (substr($e, 0, 1) === 'B' && !in_array($elem, $elements)) {
        $elements[] = $elem;
    }
}

return implode(',', $elements);

转换为编写函数表达式

return Stream::of(' B1 ', ' B2', 'a1 ', ' a2 ', 'a3', ' b1', ' b2', 'b3')
    ->map(Strings::trim())
    ->map(Strings::toUpper())
    ->filter(Strings::startsWith('B'))
    ->distinct()
    ->collect(Collectors::join(','));

入门

该库作为 Packagist.org 上的 Composer 包提供。

在你的项目中安装,只需运行

composer require dbrans/stream-pipeline

成功运行后,您可以将主类包含在应用程序逻辑中

use StreamPipeline\Stream;

用法

你可以初始化一个 Stream 来使用它

use StreamPipeline\Stream;

$arrStream = Stream::fromIterable($myArray);
// or
$arrStream = Stream::of(' B1 ', ' B2', 'a1 ', ' a2 ', 'a3', ' b1', ' b2', 'b3')

Stream 对象公开了几个方法来操作其元素

use StreamPipeline\Collectors;
use StreamPipeline\Iterators\NumberGenerator;
use StreamPipeline\Operations\Strings;

// ...

$arrStream
    ->map(Strings::trim())
    ->map(Strings::toUpper())
    ->filter(Strings::startsWith('B'))
    ->distinct()
    ->forEach(function ($e) {
        echo $e;
    });

Stream 类是不可变的,因此每个链式方法都会返回一个新的 Stream

Stream 的执行是惰性的,因此仅在调用终端操作(forEachreducetoArraycollect...)时才迭代元素。

管道操作

每个方法都允许一个可调用的参数

$arrStream
    ->filter(function ($e) {
        return $e % 2 === 0;
    })
    ->map(function ($e) {
        return $e + 10;
    })
    ->toArray();

该库公开了一些常见操作以提高可读性

$arrStream
    ->filter(Numbers::isEven())
    ->map(Numbers::plus(10))
    ->collect(Collectors::sum());

请参阅 Javadoc 获取更多信息。

Stream 方法

初始化静态操作:

  • of(...$elements): StreamInterface
  • fromIterable(iterable $collection): StreamInterface
  • iterate($initialValue, callable $stepOperation): StreamInterface

管道操作:

  • map(callable $operation): StreamInterface
  • filter(callable $operation): StreamInterface
  • peek(callable $operation): StreamInterface
  • limit(int $limit): StreamInterface
  • skip(int $number): StreamInterface
  • distinct(?callable $distinctBy = null): StreamInterface
  • flatMap(?callable $operation = null): StreamInterface
  • concat(iterable $elements): StreamInterface

终端操作:

  • findFirst()
  • count(): int
  • forEach(callable $callback): void
  • anyMatch(callable $condition): bool
  • allMatch(callable $condition): bool
  • noneMatch(callable $condition): bool
  • reduce(callable $operation, $initialValue)
  • toArray(bool $preserveKeys = false): array
  • collect(?callable $collector)

所有可调用的函数都接收参数: function ($currentElement, $index, $originalIndex)。例如

$arrStream
    ->map(function ($elem, $i, $index) {
        return ...
    })
    ->toArray();

预定义收集器

有一些预定义的收集器函数具有一些常见操作。您可以使用它们与终端运算符 collect() 一起使用。

  • Collectors::join(string $delimiter = '')
  • Collectors::sum(?callable $mapper = null)
  • Collectors::groupBy(?callable $classifier = null, ?callable $mapper = null)
  • Collectors::groupAndReduceBy(?callable $keysMapper = null, ?callable $valuesMapper = null, ?callable $reducer = null)

例如

Stream::of('a', 'b', 'c', 'd', 'e', 'f')
    ->limit(5)
    ->collect(Collectors::join(','));

迭代器类

  • NumberGenerator:一个带可选步骤的数字生成器。

示例

Stream::iterate(1, new NumberGenerator(1))
    ->filter(Numbers::isEven())
    ->skip(5)
    ->limit(11);

操作类

  • Logical:逻辑操作(如恒等、真、假...)。
  • Numbers:数字操作。
  • Objects:通用对象操作。
  • Strings:字符串工具和函数。
  • Values:多态值操作。