File tree Expand file tree Collapse file tree 5 files changed +173
-0
lines changed
src/WS/Utils/Collections/Functions/Expression
tests/WS/Utils/Collections/Functions/Expression Expand file tree Collapse file tree 5 files changed +173
-0
lines changed Original file line number Diff line number Diff line change 1+ <?php
2+ /**
3+ * @author Anton Lytkin <a.lytkin@worksolutions.ru>
4+ */
5+
6+ namespace WS \Utils \Collections \Functions \Expression ;
7+
8+ use WS \Utils \Collections \Functions \Expression \Operator \AbstractOperator ;
9+ use WS \Utils \Collections \Functions \Expression \Operator \AndOperator ;
10+ use WS \Utils \Collections \Functions \Expression \Operator \OrOperator ;
11+
12+ class BoolExpression
13+ {
14+
15+ /** @var AbstractOperator[] */
16+ private $ operators = [];
17+
18+ public function __construct (callable $ checker )
19+ {
20+ $ this ->operators [] = new AndOperator ($ checker );
21+ }
22+
23+ public static function with (callable $ checker ): self
24+ {
25+ return new self ($ checker );
26+ }
27+
28+ public function __invoke ($ item ): bool
29+ {
30+ $ operand = null ;
31+ foreach ($ this ->operators as $ operator ) {
32+ if ($ operand === null ) {
33+ if (!$ operand = $ operator ->getChecker ()($ item )) {
34+ return false ;
35+ }
36+ continue ;
37+ }
38+ if (!$ operand = $ operator ($ operand , $ item )) {
39+ return false ;
40+ }
41+ }
42+ return true ;
43+ }
44+
45+ public function and (callable $ checker ): self
46+ {
47+ $ this ->operators [] = new AndOperator ($ checker );
48+ return $ this ;
49+ }
50+
51+ public function or (callable $ checker ): self
52+ {
53+ $ this ->operators [] = new OrOperator ($ checker );
54+ return $ this ;
55+ }
56+
57+ }
Original file line number Diff line number Diff line change 1+ <?php
2+ /**
3+ * @author Anton Lytkin <a.lytkin@worksolutions.ru>
4+ */
5+
6+ namespace WS \Utils \Collections \Functions \Expression \Operator ;
7+
8+ abstract class AbstractOperator
9+ {
10+ protected $ checker ;
11+
12+ public function __construct (callable $ checker )
13+ {
14+ $ this ->checker = $ checker ;
15+ }
16+
17+ public function getChecker (): callable
18+ {
19+ return $ this ->checker ;
20+ }
21+
22+ abstract public function __invoke (bool $ operand , $ item ): bool ;
23+
24+ }
Original file line number Diff line number Diff line change 1+ <?php
2+ /**
3+ * @author Anton Lytkin <a.lytkin@worksolutions.ru>
4+ */
5+
6+ namespace WS \Utils \Collections \Functions \Expression \Operator ;
7+
8+ class AndOperator extends AbstractOperator
9+ {
10+
11+ public function __invoke (bool $ operand , $ item ): bool
12+ {
13+ if (!$ operand ) {
14+ return false ;
15+ }
16+ $ checker = $ this ->checker ;
17+ return $ checker ($ item );
18+ }
19+
20+ }
Original file line number Diff line number Diff line change 1+ <?php
2+ /**
3+ * @author Anton Lytkin <a.lytkin@worksolutions.ru>
4+ */
5+
6+ namespace WS \Utils \Collections \Functions \Expression \Operator ;
7+
8+ class OrOperator extends AbstractOperator
9+ {
10+
11+ public function __invoke (bool $ operand , $ item ): bool
12+ {
13+ if ($ operand ) {
14+ return true ;
15+ }
16+ $ checker = $ this ->checker ;
17+ return $ checker ($ item );
18+ }
19+
20+ }
Original file line number Diff line number Diff line change 1+ <?php
2+ /**
3+ * @author Anton Lytkin <a.lytkin@worksolutions.ru>
4+ */
5+
6+ namespace WS \Utils \Collections \Functions \Expression ;
7+
8+ use PHPUnit \Framework \TestCase ;
9+ use WS \Utils \Collections \CollectionFactory ;
10+
11+ class BoolExpressionTest extends TestCase
12+ {
13+
14+ public function cases ()
15+ {
16+ return [
17+ [
18+ [1 , 2 , 3 ],
19+ BoolExpression::with (function ($ element ) {
20+ return is_int ($ element );
21+ })
22+ ->or (function ($ element ) {
23+ return $ element === 77 ;
24+ })
25+ ->and (function ($ element ) {
26+ return in_array ($ element , [1 , 3 ]);
27+ }),
28+ [1 , 3 ],
29+ ],
30+ ];
31+ }
32+
33+ /**
34+ * @test
35+ * @dataProvider cases
36+ * @param array $sequence
37+ * @param BoolExpression $expression
38+ * @param array $expected
39+ */
40+ public function filterByExpression (array $ sequence , BoolExpression $ expression , array $ expected )
41+ {
42+
43+ $ result = CollectionFactory::from ($ sequence )
44+ ->stream ()
45+ ->filter ($ expression )
46+ ->getCollection ()
47+ ->toArray ();
48+
49+ self ::assertEquals ($ expected , $ result );
50+ }
51+
52+ }
You can’t perform that action at this time.
0 commit comments