sci/stream

此包的最新版本(0.0.1-alpha)没有可用的许可信息。

Stream 库

0.0.1-alpha 2015-06-27 21:43 UTC

This package is auto-updated.

Last update: 2024-09-09 00:45:44 UTC


README

Build Status

适用于数组和其它可遍历对象的链式流包装器。

在这里,我使用的“流”一词不是指PHP的流包装器,而是指类似“管道和过滤器架构”的概念——一系列“事物”的流;实际上是一个“无限的事物列表”。(参见这里。)

1. 安装

使用 composer

composer require sci/stream dev-master

2. 使用

2.1 创建流

use Sci\Stream\ArrayStream;
use Sci\Stream\IteratorStream;

// stream from array
$stream = new ArrayStream([3, 1, 4, 1, 5, 9, 2, 6, 5]);

// stream from ArrayIterator
$stream = new IteratorStream(new \ArrayIterator([2, 7, 1, 8, 2, 8]));

// stream from Generator
function generate()
{
    for ($i = 0; $i < 10; ++$i) {
        yield $i;
    }
}
$stream = new IteratorStream(generate());

2.2 映射

$incrementedValues = $stream->map(function ($value) {
    return $value + 1;
});

2.3 过滤

$smallerValues = $stream->filter(function ($value) {
    return $value < 5;
});

2.4 减少

$sum = $stream->reduce(function ($sum, $value) {
    return $sum + $value;
});

2.5 链接

流操作可以轻松链接

$stream
    ->filter(function ($value) {
        return $value < 5;
    })
    ->map(function ($value) {
        return 2 * $value;
    })
    ->reduce(function ($sum, $value) {
        return $sum + $value;
    });

2.6 获取结果

要获取流的内容,使用 foreach 迭代或 Stream::toArray() 方法

foreach ($stream as $value) {
    // $value ...
}

$array = $stream->toArray();

3. 扩展

该库可以通过子类化轻松扩展。例如,我们可以方便地添加一个CSV解析器作为流源或一些包装方法,围绕 Stream::map()Stream::filter(),以实现类似SQL的领域特定语言。(完整的示例请见 StreamExtendingTest。)

class CsvStream extends IteratorStream {
    public static function from($filename) {
        return new parent(self::readCsv($filename));
    }

    public function where(array $condition) {
        return $this->filter(function (array $row) use ($condition) {
            return ...;
        });
    }

    public function select(array $columns) {
        return $this->map(function (array $row) use ($columns) {
            $result = [];
            foreach ($columns as $column) {
                if (array_key_exists($column, $row)) {
                    $result[$column] = $row[$column];
                }
            }

            return $result;
        });
    }

    public function limit($offset, $limit) {
        // ...
    }

    private static function readCsv($filename) {
        $fd = fopen($filename, 'r');
        $header = fgetcsv($fd);
        while ($row = fgetcsv($fd)) {
            yield array_combine($header, $row);
        }
        fclose($fd);
    }
}

$csvStream = CsvStream::from('example.csv')
    ->where(['first_name' => 'Peter'])
    ->select(['first_name', 'last_name', 'street', 'zip_code', 'city'])
    ->limit(0, 10);

4. 许可证

本包所有内容均受MIT许可证的许可。