Skip to content

Commit 0ee7a5e

Browse files
committed
Modifying map to allow only key transform
1 parent 7a7ba67 commit 0ee7a5e

3 files changed

Lines changed: 78 additions & 20 deletions

File tree

src/RunOpenCode/Component/Dataset/src/Operator/Map.php

Lines changed: 16 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -6,15 +6,18 @@
66

77
use RunOpenCode\Component\Dataset\AbstractStream;
88
use RunOpenCode\Component\Dataset\Contract\OperatorInterface;
9+
use RunOpenCode\Component\Dataset\Exception\LogicException;
910

1011
/**
1112
* Map operator.
1213
*
1314
* Map operator iterates over given collection and yields transformed items.
1415
*
15-
* User must provide a callable to transform each item value. Additionally,
16-
* user may provide a callable to transform each item key. If key transform
17-
* callable is not provided, original keys are preserved.
16+
* User must provide a callable to transform each item value, or callable to
17+
* transform each item key, or both.
18+
*
19+
* Where transforming function is not provided, original values will be
20+
* preserved.
1821
*
1922
* Example usage:
2023
*
@@ -47,18 +50,22 @@ final class Map extends AbstractStream implements OperatorInterface
4750
private readonly \Closure $keyTransform;
4851

4952
/**
50-
* @param iterable<TKey, TValue> $collection Collection to iterate over.
51-
* @param ValueTransformCallable $valueTransform User defined callable to transform item values.
52-
* @param KeyTransformCallable|null $keyTransform User defined callable to transform item keys. If null, original keys are preserved.
53+
* @param iterable<TKey, TValue> $collection Collection to iterate over.
54+
* @param ValueTransformCallable|null $valueTransform User defined callable to transform item values. If null, original values are preserved.
55+
* @param KeyTransformCallable|null $keyTransform User defined callable to transform item keys. If null, original keys are preserved.
5356
*/
5457
public function __construct(
5558
private readonly iterable $collection,
56-
callable $valueTransform,
59+
?callable $valueTransform = null,
5760
?callable $keyTransform = null
5861
) {
62+
if (null === $valueTransform && null === $keyTransform) {
63+
throw new LogicException('At least one transforming function must be provided, either for key or for value.');
64+
}
65+
5966
parent::__construct($this->collection);
60-
$this->valueTransform = $valueTransform(...);
61-
$this->keyTransform = ($keyTransform ?? static fn($key, $value): mixed => $key)(...);
67+
$this->valueTransform = ($valueTransform ?? static fn(mixed $value, mixed $key): mixed => $value)(...);
68+
$this->keyTransform = ($keyTransform ?? static fn(mixed $key, mixed $value): mixed => $key)(...);
6269
}
6370

6471
/**

src/RunOpenCode/Component/Dataset/src/functions.php

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -236,18 +236,18 @@ function if_empty(iterable $collection, \Exception|callable $action): Stream
236236
* @template TModifiedKey
237237
* @template TModifiedValue
238238
*
239-
* @param iterable<TKey, TValue> $collection Collection to iterate over.
240-
* @param callable(TValue, TKey=): TModifiedValue $valueTransform User defined callable to be called on each item.
241-
* @param callable(TKey, TValue=): TModifiedKey|null $keyTransform User defined callable to be called on each item key. If null, original keys are preserved.
239+
* @param iterable<TKey, TValue> $collection Collection to iterate over.
240+
* @param callable(TValue, TKey=): TModifiedValue|null $valueTransform User defined callable to be called on each item. If null, original values are preserved.
241+
* @param callable(TKey, TValue=): TModifiedKey|null $keyTransform User defined callable to be called on each item key. If null, original keys are preserved.
242242
*
243-
* @return Stream<($keyTransform is null ? TModifiedKey : TKey), TModifiedValue>
243+
* @return Stream<($keyTransform is null ? TKey : TModifiedKey), ($valueTransform is null ? TValue : TModifiedValue)>
244244
*
245245
* @see Operator\Map
246246
*/
247-
function map(iterable $collection, callable $valueTransform, ?callable $keyTransform = null): Stream
247+
function map(iterable $collection, ?callable $valueTransform = null, ?callable $keyTransform = null): Stream
248248
{
249249
/**
250-
* @var StreamInterface<($keyTransform is null ? TKey : TModifiedKey), TModifiedValue> $map
250+
* @var StreamInterface<($keyTransform is null ? TKey : TModifiedKey), ($valueTransform is null ? TValue : TModifiedValue)> $map
251251
*/
252252
$map = new Operator\Map($collection, $valueTransform, $keyTransform);
253253

src/RunOpenCode/Component/Dataset/tests/Operator/MapTest.php

Lines changed: 56 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -6,20 +6,21 @@
66

77
use PHPUnit\Framework\Attributes\Test;
88
use PHPUnit\Framework\TestCase;
9+
use RunOpenCode\Component\Dataset\Exception\LogicException;
910

1011
use function RunOpenCode\Component\Dataset\map;
1112

1213
final class MapTest extends TestCase
1314
{
1415
#[Test]
15-
public function maps(): void
16+
public function map(): void
1617
{
1718
$operator = map(
1819
[
19-
'a' => 1,
20-
'b' => 2,
21-
'c' => 3,
22-
],
20+
'a' => 1,
21+
'b' => 2,
22+
'c' => 3,
23+
],
2324
static fn(int $value): int => $value * 2,
2425
static fn(string $key): string => \sprintf('mapped_%s', $key),
2526
);
@@ -30,4 +31,54 @@ public function maps(): void
3031
'mapped_c' => 6,
3132
], \iterator_to_array($operator));
3233
}
34+
35+
#[Test]
36+
public function map_keys(): void
37+
{
38+
$operator = map(
39+
[
40+
'a' => 1,
41+
'b' => 2,
42+
'c' => 3,
43+
],
44+
keyTransform: static fn(string $key): string => \sprintf('mapped_%s', $key),
45+
);
46+
47+
$this->assertSame([
48+
'mapped_a' => 1,
49+
'mapped_b' => 2,
50+
'mapped_c' => 3,
51+
], \iterator_to_array($operator));
52+
}
53+
54+
#[Test]
55+
public function map_values(): void
56+
{
57+
$operator = map(
58+
[
59+
'a' => 1,
60+
'b' => 2,
61+
'c' => 3,
62+
],
63+
valueTransform: static fn(int $value): int => $value * 2,
64+
);
65+
66+
$this->assertSame([
67+
'a' => 2,
68+
'b' => 4,
69+
'c' => 6,
70+
], \iterator_to_array($operator));
71+
}
72+
73+
#[Test]
74+
public function map_throws_exception_when_transform_function_missing(): void
75+
{
76+
$this->expectException(LogicException::class);
77+
78+
map([
79+
'a' => 1,
80+
'b' => 2,
81+
'c' => 3,
82+
]);
83+
}
3384
}

0 commit comments

Comments
 (0)