问题描述
我要实现的是FizzBuzz的模式匹配版本。 类似于Swift中仅使用JavaScript的版本。
如果一个数字可被3 console.log Fizz整除,如果被5整除,则Buzz如果被两个FizzBuzz整除,则两者都不记录。 我面临的挑战是:
function fizzBuzz(numbers) {
for (number in numbers) {
let div3 = number % 3 == 0 ? true : false;
let div5 = number % 5 == 0 ? true : false;
switch ([div3,div5]) {
case [true,true]:
console.log("FizzBuzz");
break;
case [true,false]:
console.log("Fizz");
break;
case [false,true]:
console.log("Buzz");
break;
case [false,false]:
console.log(number);
break;
}
}
}
var array = [...Array(100).keys()];
fizzBuzz(array);
这不起作用,我尝试没有方括号,但是只有第一个变量被求值,而另一个变量被忽略。有人可以帮我一下吗? 在Swift中,这非常简单,并且可以完美地工作,我正在尝试在JS中实现同样的效果。
我尝试了这个,但是像上面提到的那样,只求方括号中的第一个变量div3,div5被完全忽略:
function fizzBuzz(numbers) {
for (number in numbers) {
let div3 = number % 3 == 0 ? true : false;
let div5 = number % 5 == 0 ? true : false;
switch (div3,div5) {
case (true,true):
console.log("FizzBuzz");
break;
case (true,false):
console.log("Fizz");
break;
case (false,true):
console.log("Buzz");
break;
case (false,false):
console.log(number);
break;
}
}
}
var array = [...Array(100).keys()];
fizzBuzz(array);
我甚至想在JS中实现这样的语法吗?
解决方法
不确定这是否是愚蠢的方法:
const case_signature = (...args) => JSON.stringify(args);
function fizzBuzz(numbers) {
for (number in numbers) {
let div3 = number % 3 === 0;
let div5 = number % 5 === 0;
switch (case_signature(div3,div5)) {
case case_signature(true,true):
console.log("FizzBuzz");
break;
case case_signature(true,false):
console.log("Fizz");
break;
case case_signature(false,true):
console.log("Buzz");
break;
case case_signature(false,false):
console.log(number);
break;
}
}
}
var array = [...Array(100).keys()];
fizzBuzz(array);
另一种方式(但不确定是否满足您的要求):
const multi_mod = (number,...divisors) =>
number % divisors.reduce((acc,div) => acc = acc * div,1);
function fizzBuzz(numbers) {
for (number in numbers) {
switch (0) {
case multi_mod(number,3,5):
console.log("FizzBuzz");
break;
case multi_mod(number,3):
console.log("Fizz");
break;
case multi_mod(number,5):
console.log("Buzz");
break;
default:
console.log(number);
}
}
}
var array = [...Array(100).keys()];
fizzBuzz(array);
我真的不知道什么是元组,但是也许这有点像您的原始问题:
// array_equal borrowed from https://stackoverflow.com/a/19746771/14454939
const array_equal = (array1,array2) =>
array1.length === array2.length && array1.every((value,index) => value === array2[index]);
const switch_tuple = (compare) => (...cases) => {
for (let i = 0; i < cases.length; i++) {
const result = array_equal(compare,cases[i][0]);
if (result) {
cases[i][1]();
return result;
}
}
};
function fizzBuzz(numbers) {
for (number in numbers) {
let div3 = number % 3 == 0 ? true : false;
let div5 = number % 5 == 0 ? true : false;
switch_tuple([div3,div5])(
[[true,true],() => console.log("FizzBuzz")
],[[true,false],() => console.log("Fizz")
],[[false,() => console.log("Buzz")
],() => console.log(number)
],)
}
}
var array = [...Array(100).keys()];
fizzBuzz(array);
,
switch/case
使用===
运算符比较值。这是通过标识而不是内容来比较数组,因此您不能像尝试过的那样将其与数组文字一起使用。
JavaScript没有元组。 div3,div5
使用comma operator,它只是将其评估为div5
的值。
如果您想要类似您的编码模式的内容,我认为您可以做的最好的就是使用JSON。
function fizzBuzz(numbers) {
for (number in numbers) {
let div3 = number % 3 == 0 ? true : false;
let div5 = number % 5 == 0 ? true : false;
switch (JSON.stringify([div3,div5])) {
case '[true,true]':
console.log("FizzBuzz");
break;
case '[true,false]':
console.log("Fizz");
break;
case '[false,true]':
console.log("Buzz");
break;
case '[false,false]':
console.log(number);
break;
}
}
}
var array = [...Array(100).keys()];
fizzBuzz(array);
,
您还可以将布尔数组转换为数字,然后将其用于打开:
const pattern = (...args) => args.reduce((s,n,i) => s + n << i,0);
switch(pattern(true,false)) {
case pattern(false,false):
//...
}