我有一个代码,该代码可以识别数组中的运算符,并使用来基于另一个数组进行计算。下面是代码
function interpret(...args) {
let operators = args[1]; //get the operators array
let values = args[2] //numbers expect the first one.
return values.reduce((ac, val, i) => {
//check the operator at the 'i' on which we are on while iterating through 'value'
if (operators[i] === '+') return ac + val;
if (operators[i] === '-') return ac - val;
if (operators[i] === '*') return ac * val;
if (operators[i] === '/') return ac / val;
else return -1;
}, args[0]) //'ac' is initially set to first value.
}
console.log(interpret(1, ["+"], [1]))
console.log(interpret(4, ["-"], [2]))
console.log(interpret(1, ["+", "*"], [1, 3]))
console.log(interpret(5, ["+", "*", "-"], [4, 1, 3]))
console.log(interpret(10, ['*', '$', '+'], [5, 3, 2])) //It fails in this case and gives 1
请协助解决此问题。谢谢
答案 0 :(得分:1)
您可以设置一个标志,例如invalid
,以便您的reduce函数仅在发现无效的运算符时返回-1
:
function interpret(...args) {
let operators = args[1]; //get the operators array
let invalid = false; // no invalid operators
let values = args[2] //numbers expect the first one.
return values.reduce((ac, val, i) => {
//check the operator at the 'i' on which we are on while iterating through 'value'
if (!invalid) { // if invalid is false then:
if (operators[i] === '+') return ac + val;
if (operators[i] === '-') return ac - val;
if (operators[i] === '*') return ac * val;
if (operators[i] === '/') return ac / val;
}
// If invalid is true or the above operators did not match, then
invalid = true; // this will only be set to true if the above if statments didn't run
return -1 // return -1 (this will always be executred from now on as the if(!invalid) will not run the code within it anymore
}, args[0]) //'ac' is initially set to first value.
}
console.log(interpret(1, ["+"], [1]))
console.log(interpret(4, ["-"], [2]))
console.log(interpret(1, ["+", "*"], [1, 3]))
console.log(interpret(5, ["+", "*", "-"], [4, 1, 3]))
console.log(interpret(10, ['*', '$', '+'], [5, 3, 2])) // -1
或者,您可以使用一种新方法来实现此目的,例如递归解决方案:
const oper = {
'+': (a, b) => a + b,
'-': (a, b) => a - b,
'*': (a, b) => a * b,
'/': (a, b) => a / b
};
const interpret = (n, [fc, ...calcs], [fn, ...nums]) => {
if(fc === undefined) return n;
if(!(fc in oper)) return -1;
return interpret(oper[fc](n, fn), calcs, nums)
}
console.log(interpret(1, ["+"], [1]))
console.log(interpret(4, ["-"], [2]))
console.log(interpret(1, ["+", "*"], [1, 3]))
console.log(interpret(5, ["+", "*", "-"], [4, 1, 3]))
console.log(interpret(10, ['*', '$', '+'], [5, 3, 2])) // -1
答案 1 :(得分:0)
我建议将所有可能的操作存储在operator => function
的映射中,例如:
const operations = {
"+": function(a, b) { return a + b; },
"-": function(a, b) { return a - b; },
"*": function(a, b) { return a * b; },
"/": function(a, b) { return a / b; }
};
然后您可以执行该操作,如果不存在该操作,请返回NaN
以将最终结果转换为NaN
。最后,只需检查结果是否为NaN
,然后返回-1
。另外,如果您只能声明变量,我也不建议使用arguments
。
const operations = {
"+": (a, b) => a + b,
"-": (a, b) => a - b,
"*": (a, b) => a * b,
"/": (a, b) => a / b
};
function empty() { return NaN; }
function numberOrDefault(res, def) { return isNaN(res) ? def : res; }
function interpret(start, operators, values) {
return numberOrDefault(values.reduce((acc, val, i) => (operations[operators[i]] || empty)(acc, val), start), -1);
}
console.log(interpret(1, ["+"], [1]));
console.log(interpret(4, ["-"], [2]));
console.log(interpret(1, ["+", "*"], [1, 3]));
console.log(interpret(5, ["+", "*", "-"], [4, 1, 3]));
console.log(interpret(10, ['*', '$', '+'], [5, 3, 2]));
如果您不想更改任何内容,请使用以下更改最少的解决方案:
function interpret(...args) {
let operators = args[1]; //get the operators array
let values = args[2] //numbers expect the first one.
let result = values.reduce((ac, val, i) => {
//check the operator at the 'i' on which we are on while iterating through 'value'
if (operators[i] === '+') return ac + val;
if (operators[i] === '-') return ac - val;
if (operators[i] === '*') return ac * val;
if (operators[i] === '/') return ac / val;
else return NaN;
}, args[0]); //'ac' is initially set to first value.
return isNaN(result) ? -1 : result;
}
console.log(interpret(1, ["+"], [1]))
console.log(interpret(4, ["-"], [2]))
console.log(interpret(1, ["+", "*"], [1, 3]))
console.log(interpret(5, ["+", "*", "-"], [4, 1, 3]))
console.log(interpret(10, ['*', '$', '+'], [5, 3, 2]))
答案 2 :(得分:0)
如果要扫描操作和验证给定输入合理性的值,我实际上会在解释之前添加一个“解析”阶段 为避免任何可能的意外,我将实际解释括在try / catch中。
我也非常喜欢尼克的解决方案,所以我将从中得到一些启发。
const oper = {
'+': (a, b) => a + b,
'-': (a, b) => a - b,
'*': (a, b) => a * b,
'/': (a, b) => a / b
};
const opers = Object.keys(oper)
function interpret(...args) {
let operators = args[1];
let values = args[2]
const validOperators = operators.every(op => opers.includes(op) )
const validValues = values.every(val => typeof val === "number" )
if(!validOperators || !validValues)
return -1
try {
return values.reduce((ac, val, i) => {
const curOper = operators[i]
return oper[curOper](ac, val)
}, args[0])
} catch(e){
return -1
}
}
console.log(interpret(1, ["+"], [1]))
console.log(interpret(4, ["-"], [2]))
console.log(interpret(1, ["+", "*"], [1, 3]))
console.log(interpret(5, ["+", "*", "-"], [4, 1, 3]))
console.log(interpret(10, ['*', '$', '+'], [5, 3, 2]))
console.log(interpret(10, ['*', '*', '+'], [5, 3, "dog"]))
答案 3 :(得分:0)
以下演示:
calc(operators, numbers)
0:
+
, 1:-
, 2:*
, 3:/
例如 [0、1、3、3、2] 是+
,-
,/
,/
,*
>
为获得最佳操作:
例如
calc([1, 0, 3], [24, 88, 185, 11]) //11
最佳输入以外的行为:
例如
calc([1, 0, 3], [24, 88, 185, 11, 325]) //11
例如
calc([1, 0, 3, 2, 1], [24, 88, 185, 11]) //11
例如
calc([1, 0, 3], [11]) //11
我将第一个参数设置为数字数组,因为字符串可能很乱,而且除非有意进行,否则任何输入都应该有0%的机会是非数字的。链式三元确定reduce()
的每个迭代的运算符。运算符不声明initialValue
,而是在第二次迭代中加入,以便处理交替模式:
// First iteration: numbers[0] // Accumulator // Second iteration: operators[0], numbers[0] /* Accumulator */ numbers[1] // currentValue
/*
@Params
|-operators: Array of numbers | range [0-3]
| 0: +, 1: -, 2: *, 3: /
|-numbers: Array of floats
| numbers.length = operators.length + 1
@Return
|-a float
*/
const calc = ([...opr], [...num]) => {
return num.reduce((acc, cur, idx) => {
if (num.length - opr.length !== 1) {
num.length = opr.length + 1
}
if (idx > 0) {
let op = opr[idx - 1];
let exp = (op === 0) ? acc + cur : (op === 1) ? acc - cur : (op === 2) ? acc * cur : (op === 3) ? acc / cur : acc + 0;
return exp;
}
});
}
console.log(calc([1], [1, 5, 22]));
console.log(calc([0, 1], [55, 2, 0.3]));
console.log(calc([2, 3], [22, 6]));
console.log(calc([3, 1, 2], [51, 3, 3, 5]));
console.log(calc([1, 0, 3], [24, 88, 185, 11]));
console.log(calc([0], [94]));
console.log(calc([5, 6, 1], [94, 22]));