How can I use an array as case parameter in switch case?
switch ("value")
case ArrayOfStrings // check every array item to be match with value
...
How can I use an array as case parameter in switch case?
switch ("value")
case ArrayOfStrings // check every array item to be match with value
...
Share
Improve this question
edited May 27, 2020 at 11:42
Mohammadreza
asked May 27, 2020 at 11:37
MohammadrezaMohammadreza
831 gold badge1 silver badge10 bronze badges
7
-
3
Do you want to check if a specific array is passed or if the array constructor function is passed? The former is not possible in a
switch
, the latter is possible but rather odd. – VLAZ Commented May 27, 2020 at 11:39 -
1
Can you give a more detailed example of what you are trying to achieve, such as an example of what
...
might be? Is theArray
in your example literally theArray
type, so you are wanting to switch on the type? – lurker Commented May 27, 2020 at 11:40 - do yoi have a use case for it? what about the other cases? – Nina Scholz Commented May 27, 2020 at 11:41
- What is the input for your switch? Is that an array, or are you trying to match one value against an array of values? – Ivar Commented May 27, 2020 at 11:41
- 2 Clean is quite subjective. I find that way very clean. Maybe your solution would be to not use a switch statement, but you haven't provided enough detail for us to determine that. This looks a bit like an XY problem. – Ivar Commented May 27, 2020 at 11:46
4 Answers
Reset to default 8No.
This
switch ("value") {
case ArrayOfStrings // check every array item to be match with value
...
does not work, because the value of switch
and the value of case
is checked with a Identity/strict equality operator ===
parison.
It is not possible to check a value agains a value of the array.
Any other construction, like
switch (true) {
case ArrayOfStrings.includes("value"): // check every array item to be match with value
would work, but if you have only to check a single value and not other constraints, you better take
if (ArrayOfStrings.includes("value")) {
// ...
}
I've a workaround using find :
const CARS = ['RENAULT', 'FORD']
const SUV = ['PORSCHE', 'LAMBUGININININ']
const SCOOTER = ['HONDA']
function select(vehicule) {
switch (vehicule) {
// Alternative use `case undefined: return 'precatch undefined`'
case vehicule !== undefined && CARS.find(_ => _ === vehicule): return 'CARS';
case vehicule !== undefined && SUV.find(_ => _ === vehicule): return 'SUV'
case vehicule !== undefined && SCOOTER.find(_ => _ === vehicule): return 'SCOOTER';
default: return 'noop';
}
}
['', null, undefined, 'WHATEVER', 'HONDA', 'RENAULT']
.forEach(_ => console.log(_, ' - ', select(_)))
/**
Expected result:
- noop
null - noop
undefined - noop
WHATEVER - noop
HONDA - SCOOTER
RENAULT - CARS
**/
Not sure how this method is discouraged but sounds not so bad.
Well first I would suggest using if
with something like Array.isArray
:
if (Array.isArray(value)) {
// check array items
}
But, if you really want/need to check by paring to Array
constructor:
const check = (value) => {
switch (value.constructor) {
case Array:
console.log('array');
break;
// For example
case Number:
console.log('number');
break;
}
}
check(7); // 'number'
check([]); // 'array'
I would really discourage from using this approach though.
In theory, you could do that to distinguish between different constructors.
class ArrayOfStrings extends Array<string> {};
class ArrayOfNumbers extends Array<number> {};
function main(input: ArrayOfStrings | ArrayOfNumbers): void {
switch (input.constructor) {
case ArrayOfStrings:
console.log('It was an array of strings!');
break;
default:
console.log('It was something else');
}
}
main(new ArrayOfStrings('foo', 'bar')); // Logs 'It was an array of strings!'
main(new ArrayOfNumbers(1, 2)); // Logs 'It was something else'
However, this method has limitations.
- It doesn't work with subclassing.
input
will be of the same type for eachcase
— as opposed to being discriminated. See TypeScript Playground.- You need to create your arrays by using the
new
keyword.
It's better to use if
statements bined with type guards instead.