From 9d38c417a53f1e86b438f5d3ce8a0fbc5349ef47 Mon Sep 17 00:00:00 2001 From: clementzarch Date: Thu, 25 May 2023 09:14:47 +0200 Subject: [PATCH] add a "mapValues" expression that will do a preg_match --- README.md | 1 + src/ArrayExpressionLanguageProvider.php | 1 + src/MapValues.php | 87 +++++++++++++++++++++++++ 3 files changed, 89 insertions(+) create mode 100644 src/MapValues.php diff --git a/README.md b/README.md index 6ca2d0f..e54a288 100644 --- a/README.md +++ b/README.md @@ -49,6 +49,7 @@ List of available functions * `reduce(callable $callback, iterable $source) : string` * `list(int $length, mixed $value) : iterable` * `arrayFilter(array $array, ?callable $callback = null) : array` +* `mapValues(array $input, iterable $values) : array` #### Functions that can be used with `reduce` diff --git a/src/ArrayExpressionLanguageProvider.php b/src/ArrayExpressionLanguageProvider.php index fa73ea3..715c1ba 100644 --- a/src/ArrayExpressionLanguageProvider.php +++ b/src/ArrayExpressionLanguageProvider.php @@ -26,6 +26,7 @@ public function getFunctions(): array new ExtractData('extractData'), new List_('list'), new FilterList('filterList'), + new MapValues('mapValues'), ]; } } diff --git a/src/MapValues.php b/src/MapValues.php new file mode 100644 index 0000000..122174e --- /dev/null +++ b/src/MapValues.php @@ -0,0 +1,87 @@ +compile(...)->bindTo($this), + $this->evaluate(...)->bindTo($this) + ); + } + + private function compile(string $input, string $values): string + { + return << \$replacement) { + \$patterns[] = '('.\$pattern.')'; + \$replacements[] = \$replacement; + } + + \$pattern = '/^' . implode('|', \$patterns) . '$/'; + + if (is_iterable(\$inputs)) { + foreach (\$inputs as \$key => \$input) { + preg_match(\$pattern, (string) \$input, \$matches); + + if (empty(\$matches)) { + throw new \Exception(sprintf( + 'No replacement found for value "%s". Expected values: %s', + \$input, + implode(', ', array_keys(\$replacements)) + )); + } + + array_shift(\$matches); + \$inputs[\$key] = \$replacements[array_keys(array_filter(\$matches))[0]]; + } + } + + return \$inputs; + })() + PHP; + } + + private function evaluate(array $context, array $input, array $values) + { + $inputs = $input; + $patterns = []; + $replacements = []; + foreach ($values as $pattern => $replacement) { + $patterns[] = '('.$pattern.')'; + $replacements[] = $replacement; + } + + $pattern = '/^' . implode('|', $patterns) . '$/'; + + if (is_iterable($inputs)) { + foreach ($inputs as $key => $input) { + preg_match($pattern, (string) $input, $matches); + + if (empty($matches)) { + throw new \Exception(sprintf( + 'No replacement found for value "%s". Expected values: %s', + $input, + implode(', ', array_keys($replacements)) + )); + } + + array_shift($matches); + $inputs[$key] = $replacements[array_keys(array_filter($matches))[0]]; + } + } + + return $inputs; + } +}