Skip to content

Commit 4052d03

Browse files
committed
feat: null filter
1 parent 7da8363 commit 4052d03

File tree

3 files changed

+92
-8
lines changed

3 files changed

+92
-8
lines changed

src/IterableObject.php

Lines changed: 14 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -27,15 +27,27 @@ final class IterableObject implements IteratorAggregate
2727
/**
2828
* @param iterable<mixed>|null $iterable
2929
*/
30-
public function __construct(?iterable $iterable = null, ?callable $filter = null, ?callable $map = null)
30+
private function __construct(?iterable $iterable = null, ?callable $filter = null, ?callable $map = null)
3131
{
3232
$this->iterable = $iterable ?? new EmptyIterator();
3333
$this->filterFn = $filter;
3434
$this->mapFn = $map;
3535
}
3636

37-
public function filter(callable $filter): self
37+
/**
38+
* @param iterable<mixed>|null $iterable
39+
*/
40+
public static function new(?iterable $iterable = null): self
3841
{
42+
return new self($iterable);
43+
}
44+
45+
public function filter(?callable $filter = null): self
46+
{
47+
$filter = $filter ?? function ($value): bool {
48+
return (bool) $value;
49+
};
50+
3951
return new self($this->iterable, $filter, $this->mapFn);
4052
}
4153

src/iterable-functions.php

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -111,7 +111,7 @@ function iterable_reduce(iterable $iterable, callable $reduce, $initial = null)
111111
/**
112112
* @param iterable<mixed> $iterable
113113
*/
114-
function iterable(iterable $iterable, ?callable $filter = null, ?callable $map = null): IterableObject
114+
function iterable(iterable $iterable): IterableObject
115115
{
116-
return new IterableObject($iterable, $filter, $map);
116+
return IterableObject::new($iterable);
117117
}

tests/IterableObjectTest.php

Lines changed: 76 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -8,11 +8,14 @@
88
use Generator;
99
use SplFixedArray;
1010

11+
use function array_values;
1112
use function BenTools\IterableFunctions\iterable;
13+
use function func_num_args;
1214
use function it;
1315
use function iterator_to_array;
1416
use function PHPUnit\Framework\assertEquals;
1517
use function PHPUnit\Framework\assertInstanceOf;
18+
use function PHPUnit\Framework\assertSame;
1619
use function test;
1720

1821
$dataProvider = static function (): Generator {
@@ -52,11 +55,29 @@ static function ($value): bool {
5255
];
5356
};
5457

58+
/**
59+
* @param iterable<mixed> $iterable
60+
*/
61+
function create_iterable(iterable $iterable, ?callable $filter = null, ?callable $map = null): IterableObject
62+
{
63+
$object = iterable($iterable);
64+
65+
if ($filter !== null && func_num_args() > 1) {
66+
$object = $object->filter($filter);
67+
}
68+
69+
if ($map !== null) {
70+
$object = $object->map($map);
71+
}
72+
73+
return $object;
74+
}
75+
5576
test(
5677
'input: array | output: traversable',
5778
/** @param array<int, mixed> $data */
5879
function (array $data, ?callable $filter, ?callable $map, array $expectedResult): void {
59-
$iterableObject = iterable($data, $filter, $map);
80+
$iterableObject = create_iterable($data, $filter, $map);
6081
assertEquals($expectedResult, iterator_to_array($iterableObject));
6182
}
6283
)->with($dataProvider());
@@ -65,7 +86,7 @@ function (array $data, ?callable $filter, ?callable $map, array $expectedResult)
6586
'input: array | output: array',
6687
/** @param array<int, mixed> $data */
6788
function (array $data, ?callable $filter, ?callable $map, array $expectedResult): void {
68-
$iterableObject = iterable($data, $filter, $map);
89+
$iterableObject = create_iterable($data, $filter, $map);
6990
assertEquals($expectedResult, $iterableObject->asArray());
7091
}
7192
)->with($dataProvider());
@@ -75,7 +96,7 @@ function (array $data, ?callable $filter, ?callable $map, array $expectedResult)
7596
/** @param array<int, mixed> $data */
7697
function (array $data, ?callable $filter, ?callable $map, array $expectedResult): void {
7798
$data = SplFixedArray::fromArray($data);
78-
$iterableObject = iterable($data, $filter, $map);
99+
$iterableObject = create_iterable($data, $filter, $map);
79100
assertEquals($expectedResult, iterator_to_array($iterableObject));
80101
}
81102
)->with($dataProvider());
@@ -85,11 +106,32 @@ function (array $data, ?callable $filter, ?callable $map, array $expectedResult)
85106
/** @param array<int, mixed> $data */
86107
function (array $data, ?callable $filter, ?callable $map, array $expectedResult): void {
87108
$data = SplFixedArray::fromArray($data);
88-
$iterableObject = iterable($data, $filter, $map);
109+
$iterableObject = create_iterable($data, $filter, $map);
89110
assertEquals($expectedResult, $iterableObject->asArray());
90111
}
91112
)->with($dataProvider());
92113

114+
it('does not filter by default', function (): void {
115+
$data = [
116+
null,
117+
false,
118+
true,
119+
0,
120+
1,
121+
'0',
122+
'1',
123+
'',
124+
'foo',
125+
];
126+
127+
$generator = function (array $data): Generator {
128+
yield from $data;
129+
};
130+
131+
assertSame($data, iterable($data)->asArray());
132+
assertSame($data, iterable($generator($data))->asArray());
133+
});
134+
93135
it('filters the subject', function (): void {
94136
$filter =
95137
/** @param mixed $value */
@@ -100,6 +142,36 @@ static function ($value): bool {
100142
assertEquals([1 => 'bar'], iterator_to_array($iterableObject));
101143
});
102144

145+
it('uses a truthy filter by default when filter() is invoked without arguments', function (): void {
146+
$data = [
147+
null,
148+
false,
149+
true,
150+
0,
151+
1,
152+
'0',
153+
'1',
154+
'',
155+
'foo',
156+
];
157+
158+
$truthyValues = [
159+
true,
160+
1,
161+
'1',
162+
'foo',
163+
];
164+
165+
$generator = function (array $data): Generator {
166+
yield from $data;
167+
};
168+
169+
assertSame($data, iterable($data)->asArray());
170+
assertSame($data, iterable($generator($data))->asArray());
171+
assertSame($truthyValues, array_values(iterable($data)->filter()->asArray()));
172+
assertSame($truthyValues, array_values(iterable($generator($data))->filter()->asArray()));
173+
});
174+
103175
it('maps the subject', function (): void {
104176
$map = 'strtoupper';
105177
$iterableObject = iterable(['foo', 'bar'])->map($map);

0 commit comments

Comments
 (0)