繁体   English   中英

如果存在无法识别的运算符javascript,则返回一个值

[英]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到3之间的整数数组:

    0: +1: -2: *3: /
    恩。 [0,1,3,3,2]+-//*

  • 第二个参数是要计算的浮点数组。
  • 为了实现最佳操作:

    • 第二个参数的长度应比第一个参数的长度大一倍

      恩。 calc([1, 0, 3], [24, 88, 185, 11]) //11

  • 最佳输入以外的行为:

    • 如果第二个参数的长度的长度比第一个参数的长度大2或更大,则第二个参数的长度将被截断,使其长度比第一个参数大一个。

      恩。 calc([1, 0, 3], [24, 88, 185, 11, 325]) //11

    • 如果两个参数的长度相等或第一个参数的长度大于第二个参数的长度,则第一个参数中的多余数字将被忽略。

      恩。 calc([1, 0, 3, 2, 1], [24, 88, 185, 11]) //11

    • 如果第二个参数中只有一个数字,或者第一个参数中的数字不是[0-3],则返回该数字。 这种行为就像计算器处理错误输入的方式一样。

      恩。 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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM