Skip to content

Commit f244135

Browse files
authored
Expanded Contains to support also arrays (#1387)
1 parent a3b54d7 commit f244135

File tree

4 files changed

+91
-3
lines changed

4 files changed

+91
-3
lines changed
Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
<?php
2+
3+
declare(strict_types=1);
4+
5+
use function Flow\ETL\DSL\{data_frame, from_array, lit, ref, to_stream, when};
6+
7+
require __DIR__ . '/../../../autoload.php';
8+
9+
data_frame()
10+
->read(from_array([
11+
['id' => 1, 'email' => '[email protected]', 'active' => true, 'tags' => ['foo', 'bar']],
12+
['id' => 2, 'email' => '[email protected]', 'active' => false, 'tags' => ['biz', 'bar']],
13+
['id' => 3, 'email' => '[email protected]', 'active' => true, 'tags' => ['bar', 'baz']],
14+
]))
15+
->collect()
16+
->withEntry(
17+
'is_special',
18+
when(
19+
ref('active')->isTrue()->and(ref('tags')->contains('foo')),
20+
lit(true),
21+
lit(false)
22+
)
23+
)
24+
->write(to_stream(__DIR__ . '/output.txt', truncate: false))
25+
->run();
Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
+----+---------------------+--------+---------------+------------+
2+
| id | email | active | tags | is_special |
3+
+----+---------------------+--------+---------------+------------+
4+
| 1 | [email protected] | true | ["foo","bar"] | true |
5+
| 2 | [email protected] | false | ["biz","bar"] | false |
6+
| 3 | [email protected] | true | ["bar","baz"] | false |
7+
+----+---------------------+--------+---------------+------------+
8+
3 rows

src/core/etl/src/Flow/ETL/Function/Contains.php

Lines changed: 11 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44

55
namespace Flow\ETL\Function;
66

7+
use function Flow\ETL\DSL\{type_array, type_string};
78
use Flow\ETL\Row;
89

910
final class Contains extends ScalarFunctionChain
@@ -16,13 +17,21 @@ public function __construct(
1617

1718
public function eval(Row $row) : bool
1819
{
19-
$haystack = (new Parameter($this->haystack))->asString($row);
20+
$haystack = (new Parameter($this->haystack))->as($row, type_string(), type_array());
2021
$needle = (new Parameter($this->needle))->asString($row);
2122

2223
if ($haystack === null || $needle === null) {
2324
return false;
2425
}
2526

26-
return \str_contains($haystack, $needle);
27+
if (\is_string($haystack)) {
28+
return \str_contains($haystack, $needle);
29+
}
30+
31+
if (\is_array($haystack)) {
32+
return \in_array($needle, $haystack, true);
33+
}
34+
35+
return false;
2736
}
2837
}

src/core/etl/tests/Flow/ETL/Tests/Integration/Function/ContainsTest.php

Lines changed: 47 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@
55
namespace Flow\ETL\Tests\Integration\Function;
66

77
use function Flow\ETL\DSL\data_frame;
8-
use function Flow\ETL\DSL\{from_array, lit, ref, to_memory};
8+
use function Flow\ETL\DSL\{from_array, lit, not, ref, to_memory};
99
use Flow\ETL\Memory\ArrayMemory;
1010
use Flow\ETL\Tests\FlowTestCase;
1111

@@ -33,6 +33,29 @@ public function test_contains() : void
3333
);
3434
}
3535

36+
public function test_contains_on_array() : void
37+
{
38+
(data_frame())
39+
->read(
40+
from_array(
41+
[
42+
['key' => 'value', 'tags' => ['A', 'B']],
43+
]
44+
)
45+
)
46+
->withEntry('contains', ref('tags')->contains(lit('A')))
47+
->drop('tags')
48+
->write(to_memory($memory = new ArrayMemory()))
49+
->run();
50+
51+
self::assertSame(
52+
[
53+
['key' => 'value', 'contains' => true],
54+
],
55+
$memory->dump()
56+
);
57+
}
58+
3659
public function test_contains_on_non_string_key() : void
3760
{
3861
(data_frame())
@@ -76,4 +99,27 @@ public function test_contains_on_non_string_value() : void
7699
$memory->dump()
77100
);
78101
}
102+
103+
public function test_not_contains_on_array() : void
104+
{
105+
(data_frame())
106+
->read(
107+
from_array(
108+
[
109+
['key' => 'value', 'tags' => ['A', 'B']],
110+
]
111+
)
112+
)
113+
->withEntry('contains', not(ref('tags')->contains(lit('A'))))
114+
->drop('tags')
115+
->write(to_memory($memory = new ArrayMemory()))
116+
->run();
117+
118+
self::assertSame(
119+
[
120+
['key' => 'value', 'contains' => false],
121+
],
122+
$memory->dump()
123+
);
124+
}
79125
}

0 commit comments

Comments
 (0)