Streams
whsv26 opened this issue · 1 comments
whsv26 commented
whsv26 commented
function generateJsonLinesFile(string $path): void
{
Stream::infinite()
->map(fn() => new Foo(rand(), 1 === rand(0, 1), 1 === rand(0, 1)))
->map(fn(Foo $foo) => json_encode([$foo->a, $foo->b, $foo->c]))
->prepended(json_encode(["a", "b", "c"]))
->take(10000)
->intersperse(PHP_EOL)
->toFile($path);
}
/**
* @return list<Foo>
*/
function parseJsonLinesFile(string $path): array
{
$chars = function () use ($path): Generator {
$file = new SplFileObject($path);
while(false !== ($char = $file->fgetc())) {
yield $char;
}
$file = null;
};
return Stream::emits($chars())
->groupAdjacentBy(fn($c) => PHP_EOL === $c)
->map(function ($pair) {
return $pair[1]
->reduce(fn(string $acc, $cur) => $acc . $cur)
->getOrElse('[]');
})
->filterMap('parseFoo')
->toArray();
}
/**
* @return Option<Foo>
*/
function parseFoo(string $json): Option
{
return jsonDecode($json)
->toOption()
->filter(fn($candidate) => is_array($candidate))
->filter(fn($candidate) => array_key_exists(0, $candidate) && is_int($candidate[0]))
->filter(fn($candidate) => array_key_exists(1, $candidate) && is_bool($candidate[1]))
->filter(fn($candidate) => array_key_exists(2, $candidate) && is_bool($candidate[2]))
->map(fn($tuple) => new Foo($tuple[0], $tuple[1], $tuple[2]));
}
$path = 'out.jsonl';
generateJsonLinesFile($path);
parseJsonLinesFile($path);