Skip to content

Commit 9e5d316

Browse files
authored
Merge pull request #22 from worksolutions/bool-expression
Bool Expression functional
2 parents 6f2c28c + 6ef3b97 commit 9e5d316

File tree

5 files changed

+173
-0
lines changed

5 files changed

+173
-0
lines changed
Lines changed: 57 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,57 @@
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+
}
Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
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+
}
Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
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+
}
Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
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+
}
Lines changed: 52 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,52 @@
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+
}

0 commit comments

Comments
 (0)