Full support for arrays => min, max and avg funcs accept array argument. Also array function is defined which return arguments as array. Square bracket arrays are also supported. (#108)
valid expression -> "max([1,2,3])" valid expression -> "max(array(1,2,3))" valid expression -> "max($ages_arr)" valid expression -> "max(ages_arr())"
This commit is contained in:
parent
2874b11341
commit
5d6b4a5dfd
4 changed files with 43 additions and 7 deletions
20
README.md
20
README.md
|
@ -40,6 +40,7 @@ Default functions:
|
||||||
* arcctg (arccot, arccotan)
|
* arcctg (arccot, arccotan)
|
||||||
* arcsec
|
* arcsec
|
||||||
* arccsc (arccosec)
|
* arccsc (arccosec)
|
||||||
|
* array
|
||||||
* asin (arcsin)
|
* asin (arcsin)
|
||||||
* atan (atn, arctan, arctg)
|
* atan (atn, arctan, arctg)
|
||||||
* atan2
|
* atan2
|
||||||
|
@ -84,7 +85,10 @@ Add custom function to executor:
|
||||||
```php
|
```php
|
||||||
$executor->addFunction('abs', function($arg) {return abs($arg);});
|
$executor->addFunction('abs', function($arg) {return abs($arg);});
|
||||||
```
|
```
|
||||||
Function default parameters are not supported at this time.
|
Function default parameters (optional parameters) are also supported.
|
||||||
|
```php
|
||||||
|
$executor->addFunction('round', function($num, int $precision = 0) {return round($num, $precision);});
|
||||||
|
```
|
||||||
|
|
||||||
## Operators:
|
## Operators:
|
||||||
Default operators: `+ - * / ^`
|
Default operators: `+ - * / ^`
|
||||||
|
@ -139,12 +143,20 @@ $executor->setVar('var1', 0.15)->setVar('var2', 0.22);
|
||||||
echo $executor->execute("$var1 + var2");
|
echo $executor->execute("$var1 + var2");
|
||||||
```
|
```
|
||||||
|
|
||||||
By default, variables must be scalar values (int, float, bool or string). If you would like to support another type, use **setVarValidationHandler**
|
Arrays are also supported (as variables, as func params or can be returned in user defined funcs):
|
||||||
|
```php
|
||||||
|
$executor->setVar('monthly_salaries', [1800, 1900, 1200, 1600]);
|
||||||
|
|
||||||
|
echo $executor->execute("avg(monthly_salaries) * min([1.1, 1.3])");
|
||||||
|
```
|
||||||
|
|
||||||
|
|
||||||
|
By default, variables must be scalar values (int, float, bool or string) or array. If you would like to support another type, use **setVarValidationHandler**
|
||||||
|
|
||||||
```php
|
```php
|
||||||
$executor->setVarValidationHandler(function (string $name, $variable) {
|
$executor->setVarValidationHandler(function (string $name, $variable) {
|
||||||
// allow all scalars and null
|
// allow all scalars, array and null
|
||||||
if (is_scalar($variable) || $variable === null) {
|
if (is_scalar($variable) || is_array($variable) || $variable === null) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
// Allow variables of type DateTime, but not others
|
// Allow variables of type DateTime, but not others
|
||||||
|
|
|
@ -76,6 +76,13 @@ class Tokenizer
|
||||||
|
|
||||||
continue 2;
|
continue 2;
|
||||||
|
|
||||||
|
case '[' === $ch:
|
||||||
|
$this->tokens[] = new Token(Token::Function, 'array');
|
||||||
|
$this->allowNegative = true;
|
||||||
|
$this->tokens[] = new Token(Token::LeftParenthesis, '');
|
||||||
|
|
||||||
|
continue 2;
|
||||||
|
|
||||||
case ' ' == $ch || "\n" == $ch || "\r" == $ch || "\t" == $ch:
|
case ' ' == $ch || "\n" == $ch || "\r" == $ch || "\t" == $ch:
|
||||||
$this->tokens[] = new Token(Token::Space, '');
|
$this->tokens[] = new Token(Token::Space, '');
|
||||||
|
|
||||||
|
@ -140,7 +147,7 @@ class Tokenizer
|
||||||
|
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case $this->isRP($ch):
|
case $this->isRP($ch) || ']' === $ch :
|
||||||
$this->emptyNumberBufferAsLiteral();
|
$this->emptyNumberBufferAsLiteral();
|
||||||
$this->emptyStrBufferAsVariable();
|
$this->emptyStrBufferAsVariable();
|
||||||
$this->allowNegative = false;
|
$this->allowNegative = false;
|
||||||
|
@ -196,8 +203,8 @@ class Tokenizer
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @throws UnknownOperatorException
|
|
||||||
* @throws IncorrectBracketsException
|
* @throws IncorrectBracketsException
|
||||||
|
* @throws UnknownOperatorException
|
||||||
* @return Token[] Array of tokens in revers polish notation
|
* @return Token[] Array of tokens in revers polish notation
|
||||||
*/
|
*/
|
||||||
public function buildReversePolishNotation() : array
|
public function buildReversePolishNotation() : array
|
||||||
|
|
|
@ -469,7 +469,8 @@ class MathExecutor
|
||||||
'tan' => static fn($arg) => \tan($arg),
|
'tan' => static fn($arg) => \tan($arg),
|
||||||
'tanh' => static fn($arg) => \tanh($arg),
|
'tanh' => static fn($arg) => \tanh($arg),
|
||||||
'tn' => static fn($arg) => \tan($arg),
|
'tn' => static fn($arg) => \tan($arg),
|
||||||
'tg' => static fn($arg) => \tan($arg)
|
'tg' => static fn($arg) => \tan($arg),
|
||||||
|
'array' => static fn(...$args) => [...$args]
|
||||||
];
|
];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -305,6 +305,22 @@ class MathTest extends TestCase
|
||||||
$this->assertEquals(100, $calculator->execute('10 ^ 2'));
|
$this->assertEquals(100, $calculator->execute('10 ^ 2'));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public function testArrays() : void
|
||||||
|
{
|
||||||
|
$calculator = new MathExecutor();
|
||||||
|
$this->assertEquals([1, 5, 2], $calculator->execute('array(1, 5, 2)'));
|
||||||
|
$this->assertEquals([1, 5, 2], $calculator->execute('[1, 5, 2]'));
|
||||||
|
$this->assertEquals(\max([1, 5, 2]), $calculator->execute('max([1, 5, 2])'));
|
||||||
|
$this->assertEquals(\max([1, 5, 2]), $calculator->execute('max(array(1, 5, 2))'));
|
||||||
|
$calculator->addFunction('arr_with_max_elements', static function($arg1, ...$args) {
|
||||||
|
$args = \is_array($arg1) ? $arg1 : [$arg1, ...$args];
|
||||||
|
\usort($args, static fn($arr1, $arr2) => \count($arr2) <=> \count($arr1));
|
||||||
|
|
||||||
|
return $args[0];
|
||||||
|
});
|
||||||
|
$this->assertEquals([3, 3, 3], $calculator->execute('arr_with_max_elements([[1],array(2,2),[3,3,3]])'));
|
||||||
|
}
|
||||||
|
|
||||||
public function testFunctionParameterOrder() : void
|
public function testFunctionParameterOrder() : void
|
||||||
{
|
{
|
||||||
$calculator = new MathExecutor();
|
$calculator = new MathExecutor();
|
||||||
|
|
Loading…
Reference in a new issue