写一个计算器函数——最函数式的编程方式(javascript)
Writing a calculator function - in the most functional programming way(javascript)
我正在尝试 codewars 中的一项任务,并希望在 javascript 中以函数式编程方式编写。我对我的功能以及如何以更好的方式编写代码有一些疑问。
任务本身就是构建一个计算器函数。它将接受以下格式的输入:
'..... + ...'
计算器必须将字符串拆分为表示运算的中间字符,然后剩下的两个字符串就是两个值。在上面的示例中,第一个值为 5,第二个值为 3。完成后,根据运算符执行操作 - 加法、乘法等。
这是我的代码:
function dotCalculator(equation) {
function returnSymbol(input) {
if (input.includes(' + ')) {
return ' + ';
} else if (input.includes(' - ')) {
return ' - ';
} else if (input.includes(' * ')) {
return ' * ';
} else if (input.includes(' / ')) {
return ' / ';
}
}
let symbolOf = returnSymbol;
let result = equation.split(symbolOf(equation)).map(x => x.length);
// Array.prototype.add = function(){
// return this[0] + this[1];
// }
}
我知道我的代码还没有完成。我试图了解如何以函数式编程的思维方式正确完成它。也许原型继承会有点矫枉过正。我正在寻找任何愿意伸出援手的人的一些想法。我尝试在
之后写一个更复杂的 reduce
let arrMine = equation.split(symbolOf(equation)).map((x) => x.length);
但看起来太乱了。任何帮助将不胜感激。
此示例中的函数程序可以计算简单的算术运算——两个数字的加、减、乘或除。
详情见下方示例
注意: 在任何传递给 calc()
的负数前加上下划线 _
而不是连字符 -
// Utility function
const log = data => console.log(JSON.stringify(data));
// Arithmetic functions
const sum = (a, b) => (+a) + (+b);
const dif = (a, b) => a - b;
const pro = (a, b) => a * b;
const quo = (a, b) => a / b;
/**
* Calculate a simple formula a+b, a-b, a*b, or a/b.
* @param {string} formula - Pattern:
* "numberOPERANDnumber" ex. "5+5"
* Use an underscore to prefix negative numbers.
* @returns {number} Result of formula
*/
const calc = formula => {
// Declare variables
let result, f, a, b, op;
/*
Convert string into an array of strings.
[number, operand, number]
Replace any _ with - (see @param)
*/
f = formula.split(/([+\-*/])/)
.map(ab => ab.replace('_', '-'));
/*
Convert string of numbers into real numbers.
*/
a = parseFloat(f[0]);
b = parseFloat(f[2]);
op = f[1];
/*
Check if >a< and >b< are real numbers and if the input string was split
into 3 strings.
*/
if (Number.isNaN(a) || Number.isNaN(b) || f.length != 3) {
return;
}
// >op< determines the method of resolving the formula
switch (op) {
case '+':
result = sum(a, b);
break;
case '-':
result = dif(a, b);
break;
case '*':
result = pro(a, b);
break;
case '/':
result = quo(a, b);
break;
default:
return;
}
return result;
};
log(calc('5+5'));
log(calc('_10-7')); // That's a -10 (see @param)
log(calc('5*9'));
log(calc('51/3'));
我是一个非常函数式编程的新手,这里的管道函数可能有点无用,我可能过于字面地理解了 ..... + ...
示例,但这是一个尝试:
const arith = {
'+': (a, b) => a + b,
'-': (a, b) => a - b,
'*': (a, b) => a * b,
'/': (a, b) => a / b,
};
const pipe = (...fns) => (arg) => fns.reduce((res, fn) => fn(res), arg);
const get_input_elements = (input) => input.split(' ');
const get_number = (dots) => dots.length;
const get_numbers = ([str_a, op, str_b]) =>
[get_number(str_a), op, get_number(str_b)];
const apply_arith = ([a, op, b]) => arith[op](a, b);
const calc = pipe(
get_input_elements,
get_numbers,
apply_arith
);
console.log(calc('..... + ...'));
console.log(calc('..... - ...'));
console.log(calc('...... / ..'));
我正在尝试 codewars 中的一项任务,并希望在 javascript 中以函数式编程方式编写。我对我的功能以及如何以更好的方式编写代码有一些疑问。
任务本身就是构建一个计算器函数。它将接受以下格式的输入:
'..... + ...'
计算器必须将字符串拆分为表示运算的中间字符,然后剩下的两个字符串就是两个值。在上面的示例中,第一个值为 5,第二个值为 3。完成后,根据运算符执行操作 - 加法、乘法等。
这是我的代码:
function dotCalculator(equation) {
function returnSymbol(input) {
if (input.includes(' + ')) {
return ' + ';
} else if (input.includes(' - ')) {
return ' - ';
} else if (input.includes(' * ')) {
return ' * ';
} else if (input.includes(' / ')) {
return ' / ';
}
}
let symbolOf = returnSymbol;
let result = equation.split(symbolOf(equation)).map(x => x.length);
// Array.prototype.add = function(){
// return this[0] + this[1];
// }
}
我知道我的代码还没有完成。我试图了解如何以函数式编程的思维方式正确完成它。也许原型继承会有点矫枉过正。我正在寻找任何愿意伸出援手的人的一些想法。我尝试在
之后写一个更复杂的 reducelet arrMine = equation.split(symbolOf(equation)).map((x) => x.length);
但看起来太乱了。任何帮助将不胜感激。
此示例中的函数程序可以计算简单的算术运算——两个数字的加、减、乘或除。
详情见下方示例
注意: 在任何传递给 calc()
的负数前加上下划线 _
而不是连字符 -
// Utility function
const log = data => console.log(JSON.stringify(data));
// Arithmetic functions
const sum = (a, b) => (+a) + (+b);
const dif = (a, b) => a - b;
const pro = (a, b) => a * b;
const quo = (a, b) => a / b;
/**
* Calculate a simple formula a+b, a-b, a*b, or a/b.
* @param {string} formula - Pattern:
* "numberOPERANDnumber" ex. "5+5"
* Use an underscore to prefix negative numbers.
* @returns {number} Result of formula
*/
const calc = formula => {
// Declare variables
let result, f, a, b, op;
/*
Convert string into an array of strings.
[number, operand, number]
Replace any _ with - (see @param)
*/
f = formula.split(/([+\-*/])/)
.map(ab => ab.replace('_', '-'));
/*
Convert string of numbers into real numbers.
*/
a = parseFloat(f[0]);
b = parseFloat(f[2]);
op = f[1];
/*
Check if >a< and >b< are real numbers and if the input string was split
into 3 strings.
*/
if (Number.isNaN(a) || Number.isNaN(b) || f.length != 3) {
return;
}
// >op< determines the method of resolving the formula
switch (op) {
case '+':
result = sum(a, b);
break;
case '-':
result = dif(a, b);
break;
case '*':
result = pro(a, b);
break;
case '/':
result = quo(a, b);
break;
default:
return;
}
return result;
};
log(calc('5+5'));
log(calc('_10-7')); // That's a -10 (see @param)
log(calc('5*9'));
log(calc('51/3'));
我是一个非常函数式编程的新手,这里的管道函数可能有点无用,我可能过于字面地理解了 ..... + ...
示例,但这是一个尝试:
const arith = {
'+': (a, b) => a + b,
'-': (a, b) => a - b,
'*': (a, b) => a * b,
'/': (a, b) => a / b,
};
const pipe = (...fns) => (arg) => fns.reduce((res, fn) => fn(res), arg);
const get_input_elements = (input) => input.split(' ');
const get_number = (dots) => dots.length;
const get_numbers = ([str_a, op, str_b]) =>
[get_number(str_a), op, get_number(str_b)];
const apply_arith = ([a, op, b]) => arith[op](a, b);
const calc = pipe(
get_input_elements,
get_numbers,
apply_arith
);
console.log(calc('..... + ...'));
console.log(calc('..... - ...'));
console.log(calc('...... / ..'));