[英]Return a value if there is an unidentified operator javascript
我有一个代码,该代码可识别数组中的运算符,并使用来基于另一个数组形成计算。 下面是代码
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
请帮助解决此问题。 谢谢
您可以设置一个标志,例如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
我建议将所有可能的操作存储在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]))
如果要同时扫描操作和验证给定输入的合理性的值,那么我实际上会在解释之前添加一个“解析”阶段,为避免任何可能的意外,我将实际解释括在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"]))
以下演示:
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]));
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.