From da84df9df0259ebd9f50246277e75755627e7b72 Mon Sep 17 00:00:00 2001 From: Roberto Butti Date: Fri, 11 Oct 2024 17:14:13 +0200 Subject: [PATCH 1/2] fix, tests and document the in and has operators --- README.md | 38 ++++++++++++++++++++++-- src/Traits/QueryableBlock.php | 4 +-- tests/Feature/QueryBlockTest.php | 2 +- tests/Feature/UrlTest.php | 4 +-- tests/Unit/Traits/QueryableBlockTest.php | 31 +++++++++++++++++++ 5 files changed, 72 insertions(+), 7 deletions(-) diff --git a/README.md b/README.md index b76a99d..8f73fe7 100644 --- a/README.md +++ b/README.md @@ -437,7 +437,36 @@ If you want to avoid preserving the keys and set new integer keys starting from ``` With `where()` method you can use different operators, like "==", ">", "<" etc. -You can use also the `in` operator in the case your nested data contains arrays. + + + +You can use also the `has` operator in the case your nested data contains arrays or `in` operator in the case you want to check if your data field value is included in an array of elements. + +#### The `in` operator + +The `in` operator is used within the where method to filter elements from a data collection based on whether a specific field's value exists within a given array of values. +The behavior is as follows: + +```php +$data->where("field", "in", ["value1", "value2", ...]) +``` + +If the field's value exists in the provided array, the element is included in the result. +Example: Filtering fruits by color that match either "green" or "black" +```php +$greenOrBlack = $data->where("color", "in", ["green", "black"]); +``` + +You should use the `in` operator if your field is a scalar type (for example string or number) and you need to check if it is included in a list of values (array). + +#### The `has` operator + +The `has` operator is used within the where method to filter elements from a data collection based on whether a specific field contains a given value, typically in cases where the field holds an array or a collection of tags or attributes. The behavior is as follows: + +```php +$data->where("field", "has", "value") +``` + For example if you have posts and each post can have multiple tags, you can filter posts with a specific tag: ```php @@ -446,8 +475,13 @@ $posts = Block ::fromJsonUrl($url) ->getBlock("posts"); -$lovePosts = $posts->where("tags", "in", "love"); +$lovePosts = $posts->where("tags", "has", "love"); ``` +#### Summary `in` VS `has` + +The `in` operator filters elements by matching a field's value against an array of possible values. If the value exists in the array, the element is included in the result. An empty array returns no results. + +The `has` operator filters elements by checking if a specific value exists within a field (usually an array or a collection). If the value exists, the element is included in the result. Non-existent values return no matches. ### The `orderBy()` method You can order or sort data for a specific key. diff --git a/src/Traits/QueryableBlock.php b/src/Traits/QueryableBlock.php index d90b579..ce70d1c 100644 --- a/src/Traits/QueryableBlock.php +++ b/src/Traits/QueryableBlock.php @@ -55,8 +55,8 @@ public function where( '<=' => $elementToCheck->get($field) <= $value, '!=' => $elementToCheck->get($field) != $value, '!==' => $elementToCheck->get($field) !== $value, - 'in' => in_array($value, $elementToCheck->get($field)), - 'has' => in_array($elementToCheck->get($field), $value), + 'in' => in_array($elementToCheck->get($field), $value), + 'has' => in_array($value, $elementToCheck->get($field)), default => $elementToCheck->get($field) === $value, }; if ($found) { diff --git a/tests/Feature/QueryBlockTest.php b/tests/Feature/QueryBlockTest.php index 2211660..6c34696 100644 --- a/tests/Feature/QueryBlockTest.php +++ b/tests/Feature/QueryBlockTest.php @@ -88,7 +88,7 @@ expect($posts)->toBeInstanceOf(Block::class); expect($posts)->toHaveCount(30); - $lovePosts = $posts->where("tags", "in", "love"); + $lovePosts = $posts->where("tags", "has", "love"); expect($lovePosts)->toHaveCount(9); $mostViewedPosts = $posts->orderBy("views", "desc"); diff --git a/tests/Feature/UrlTest.php b/tests/Feature/UrlTest.php index 2fa9ae8..89b381b 100644 --- a/tests/Feature/UrlTest.php +++ b/tests/Feature/UrlTest.php @@ -23,7 +23,7 @@ expect($posts)->toBeInstanceOf(Block::class); expect($posts)->toHaveCount(30); - $lovePosts = $posts->where("tags", "in", "love"); + $lovePosts = $posts->where("tags", "has", "love"); expect($lovePosts)->toHaveCount(9); @@ -36,7 +36,7 @@ ->getBlock("posts") ->where( field: "tags", - operator: "in", + operator: "has", value: "love", preseveKeys: false, ) diff --git a/tests/Unit/Traits/QueryableBlockTest.php b/tests/Unit/Traits/QueryableBlockTest.php index 3e8ac7d..8f0814a 100644 --- a/tests/Unit/Traits/QueryableBlockTest.php +++ b/tests/Unit/Traits/QueryableBlockTest.php @@ -10,6 +10,7 @@ 'wikipedia' => 'https://en.wikipedia.org/wiki/Avocado', 'color' => 'green', 'rating' => 8, + 'tags' => ['healthy', 'creamy', 'green'], ], "apple" => [ @@ -18,6 +19,7 @@ 'wikipedia' => 'https://en.wikipedia.org/wiki/Apple', 'color' => 'red', 'rating' => 7, + 'tags' => ['classic', 'crunchy', 'juicy', 'red', 'sweet'], ], "banana" => [ @@ -26,6 +28,7 @@ 'wikipedia' => 'https://en.wikipedia.org/wiki/Banana', 'color' => 'yellow', 'rating' => 8.5, + 'tags' => ['sweet', 'soft', 'yellow'], ], "cherry" => [ @@ -34,6 +37,7 @@ 'wikipedia' => 'https://en.wikipedia.org/wiki/Cherry', 'color' => 'red', 'rating' => 9, + 'tags' => ['small', 'tart', 'red'], ], ]; @@ -77,3 +81,30 @@ function (): void { }, ); + + +test( + 'where method, in operator', + function () use ($fruitsArray): void { + $data = Block::make($fruitsArray); + $greenOrBlack = $data->where("color", "in", ["green", "black"]); + expect($greenOrBlack)->tohaveCount(1); + $noResult = $data->where("color", "in", []); + expect($noResult)->tohaveCount(0); + $greenOrRed = $data->where("color", "in", ["green", "red"]); + expect($greenOrRed)->tohaveCount(3); + }, +); + +test( + 'where method, has operator', + function () use ($fruitsArray): void { + $data = Block::make($fruitsArray); + $sweet = $data->where("tags", "has", "sweet"); + expect($sweet)->tohaveCount(2); + $noResult = $data->where("tags", "has", "not-existent"); + expect($noResult)->tohaveCount(0); + $softFruit = $data->where("tags", "has", "soft"); + expect($softFruit)->tohaveCount(1); + }, +); From 0c9a455c23e51993b145b52d9b808a17af0c1c41 Mon Sep 17 00:00:00 2001 From: Roberto Butti Date: Fri, 11 Oct 2024 17:15:12 +0200 Subject: [PATCH 2/2] Update CHANGELOG.md --- CHANGELOG.md | 1 + 1 file changed, 1 insertion(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index ee64093..e339d80 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,6 +1,7 @@ # Changelog ## WIP +- `in` and `has` operator - Implementing a Trait for formatting data - Implementing getFormattedDateTime for getting value as formatted data