From 9f41d0a432338fc26233512701b0f2f37ce0ab9f Mon Sep 17 00:00:00 2001 From: Rudolph Gottesheim Date: Thu, 21 Dec 2023 16:21:36 +0100 Subject: [PATCH] Add take() function --- README.md | 1 + src/Scope.php | 12 ++++++++++++ tests/unit/ExpressionTest.php | 8 ++++++++ 3 files changed, 21 insertions(+) diff --git a/README.md b/README.md index 1578223..d292fc5 100644 --- a/README.md +++ b/README.md @@ -106,6 +106,7 @@ The target can be any expression. It will be passed as the first argument to the | `contains` | Returns whether a list contains a value | `foo:list.contains:bool("bar")` | | `some` | Returns whether any element matches a [predicate](#lambdas) | `foo:list.some:bool(\|item\| item:int > 5)` | | `substr` | Returns a substring of a string | `foo:string.substr:string(0, 5)` | +| `take` | Returns the first n elements of a list | `foo:list.take:list(5)` | #### Custom Functions diff --git a/src/Scope.php b/src/Scope.php index bbe838e..188ccbc 100644 --- a/src/Scope.php +++ b/src/Scope.php @@ -11,6 +11,7 @@ use function array_is_list; use function array_keys; use function array_map; +use function array_slice; use function array_values; use function count; use function get_debug_type; @@ -44,6 +45,7 @@ public function __construct(private readonly array $vars = [], array $funcs = [] 'filter' => self::filter(...), 'some' => self::some(...), 'substr' => substr(...), + 'take' => self::take(...), ] : []; $shadowed = array_intersect(array_keys($predefinedFuncs), array_keys($funcs)); if ($shadowed !== []) { @@ -126,6 +128,16 @@ private static function filter(array $items, callable $predicate): array return array_is_list($items) ? array_values($out) : $out; } + /** + * @template T + * @param list $items + * @return list + */ + private static function take(array $items, int $n): array + { + return array_slice($items, 0, $n); + } + /** * @internal */ diff --git a/tests/unit/ExpressionTest.php b/tests/unit/ExpressionTest.php index ecaf5fd..6b2760d 100644 --- a/tests/unit/ExpressionTest.php +++ b/tests/unit/ExpressionTest.php @@ -126,6 +126,14 @@ public static function evaluateCases(): iterable true, ], ['myMap:map', new Scope(['myMap' => [42 => 'a', 69 => 'b']]), [42 => 'a', 69 => 'b']], + [ + 'items:list.take:list(3)', + new Scope(['items' => ['a', 'b', 'c', 'd', 'e']]), + ['a', 'b', 'c'], + ], + ['items:list.take:list(3)', new Scope(['items' => ['a', 'b']]), ['a', 'b']], + ['items:list.take:list(3)', new Scope(['items' => []]), []], + ['items:list.take:list(0)', new Scope(['items' => ['a', 'b', 'c', 'd', 'e']]), []], ]; foreach ($cases as [$expr, $scope, $expected]) { $expectedStr = (string)Expr::literal($expected);