From 1bbfe963cac0db6e7ee1b3b69d76d59950f27e63 Mon Sep 17 00:00:00 2001 From: Yigit Cukuren <42731194+yigitcukuren@users.noreply.github.com> Date: Thu, 30 May 2019 10:14:58 +0300 Subject: [PATCH] Calculation :: Added switch function (#983) --- .../Calculation/Calculation.php | 5 ++ src/PhpSpreadsheet/Calculation/Logical.php | 54 +++++++++++++++++++ .../Calculation/functionlist.txt | 1 + .../Calculation/LogicalTest.php | 16 ++++++ tests/data/Calculation/Logical/SWITCH.php | 46 ++++++++++++++++ 5 files changed, 122 insertions(+) create mode 100644 tests/data/Calculation/Logical/SWITCH.php diff --git a/src/PhpSpreadsheet/Calculation/Calculation.php b/src/PhpSpreadsheet/Calculation/Calculation.php index f49fb9d737..8ef630787c 100644 --- a/src/PhpSpreadsheet/Calculation/Calculation.php +++ b/src/PhpSpreadsheet/Calculation/Calculation.php @@ -1945,6 +1945,11 @@ class Calculation 'functionCall' => [MathTrig::class, 'SUMXMY2'], 'argumentCount' => '2', ], + 'SWITCH' => [ + 'category' => Category::CATEGORY_LOGICAL, + 'functionCall' => [Logical::class, 'statementSwitch'], + 'argumentCount' => '3+', + ], 'SYD' => [ 'category' => Category::CATEGORY_FINANCIAL, 'functionCall' => [Financial::class, 'SYD'], diff --git a/src/PhpSpreadsheet/Calculation/Logical.php b/src/PhpSpreadsheet/Calculation/Logical.php index c36e3fca74..3e6c5e7417 100644 --- a/src/PhpSpreadsheet/Calculation/Logical.php +++ b/src/PhpSpreadsheet/Calculation/Logical.php @@ -273,6 +273,60 @@ public static function statementIf($condition = true, $returnIfTrue = 0, $return return ($condition) ? $returnIfTrue : $returnIfFalse; } + /** + * STATEMENT_SWITCH. + * + * Returns corresponding with first match (any data type such as a string, numeric, date, etc). + * + * Excel Function: + * =SWITCH (expression, value1, result1, value2, result2, ... value_n, result_n [, default]) + * + * Expression + * The expression to compare to a list of values. + * value1, value2, ... value_n + * A list of values that are compared to expression. The SWITCH function is looking for the first value that matches the expression. + * result1, result2, ... result_n + * A list of results. The SWITCH function returns the corresponding result when a value matches expression. + * default + * Optional. It is the default to return if expression does not match any of the values (value1, value2, ... value_n). + * + * @category Logical Functions + * + * @param mixed $arguments Statement arguments + * + * @return mixed The value of matched expression + */ + public static function statementSwitch(...$arguments) + { + $result = Functions::VALUE(); + + if (count($arguments) > 0) { + $targetValue = Functions::flattenSingleValue($arguments[0]); + $argc = count($arguments) - 1; + $switchCount = floor($argc / 2); + $switchSatisfied = false; + $hasDefaultClause = $argc % 2 !== 0; + $defaultClause = $argc % 2 === 0 ? null : $arguments[count($arguments) - 1]; + + if ($switchCount) { + for ($index = 0; $index < $switchCount; ++$index) { + if ($targetValue == $arguments[$index * 2 + 1]) { + $result = $arguments[$index * 2 + 2]; + $switchSatisfied = true; + + break; + } + } + } + + if (!$switchSatisfied) { + $result = $hasDefaultClause ? $defaultClause : Functions::NA(); + } + } + + return $result; + } + /** * IFERROR. * diff --git a/src/PhpSpreadsheet/Calculation/functionlist.txt b/src/PhpSpreadsheet/Calculation/functionlist.txt index ee87c17f63..4a5cd265ba 100644 --- a/src/PhpSpreadsheet/Calculation/functionlist.txt +++ b/src/PhpSpreadsheet/Calculation/functionlist.txt @@ -337,6 +337,7 @@ SUMSQ SUMX2MY2 SUMX2PY2 SUMXMY2 +SWITCH SYD T TAN diff --git a/tests/PhpSpreadsheetTests/Calculation/LogicalTest.php b/tests/PhpSpreadsheetTests/Calculation/LogicalTest.php index 3dec0c7f97..37f9434e92 100644 --- a/tests/PhpSpreadsheetTests/Calculation/LogicalTest.php +++ b/tests/PhpSpreadsheetTests/Calculation/LogicalTest.php @@ -120,4 +120,20 @@ public function providerIFERROR() { return require 'data/Calculation/Logical/IFERROR.php'; } + + /** + * @dataProvider providerSwitch + * + * @param mixed $expectedResult + */ + public function testSWITCH($expectedResult, ...$args) + { + $result = Logical::statementSwitch(...$args); + self::assertEquals($expectedResult, $result); + } + + public function providerSwitch() + { + return require 'data/Calculation/Logical/SWITCH.php'; + } } diff --git a/tests/data/Calculation/Logical/SWITCH.php b/tests/data/Calculation/Logical/SWITCH.php new file mode 100644 index 0000000000..d062b7fe0e --- /dev/null +++ b/tests/data/Calculation/Logical/SWITCH.php @@ -0,0 +1,46 @@ +