将数学运算从 + 反转为 -
Inverting a math operation from + to -
我想转换 Javascript 中的数学运算。例如给定一个“-”,它应该被转换为一个“+”,“*”-“/”等等。
我现在的代码是switch case,执行起来真的很慢:
if (contents.className == "buttonfunction") {
if (invert == true) {
switch (contents.innerHTML) {
case "+":
contents.innerHTML = "-";
break;
case "-":
contents.innerHTML = "+";
break;
case "*":
contents.innerHTML = "/";
break;
case "/":
contents.innerHTML = "*";
break;
}
}
document.body.appendChild(contents);
}
这个问题有better/faster解决方案吗?
性能可以忽略不计,但对于将一个事物映射到另一个事物的操作,table-driven 方法在较长的 运行 中通常更易于维护:
const inverseOperations = {
'+': '-',
'-': '+',
'/': '*',
'*': '/',
};
if (contents.className == "buttonfunction") {
const operation = contents.innerHTML
if (invert == true && inverseOperations[operation]) {
contents.innerHTML = inverseOperations[operation];
}
document.body.appendChild(contents);
}
我添加了一些上下文来制作一个 运行 示例。
顺便说一句,这里使用的方法是反转规则映射,替换您在 switch 语句中使用的逻辑:
let invert = true;
//granular map of pairs declaring the inverse of each operator
//it could be declared inline here but it could be also fed with the addInversionInMap
let inverted = {}; //{ '+' : '-', '-' : '+', '*' : '/', '/' : '*'}
addInversionInMap('+','-');
addInversionInMap('*','/');
//feeds the inverted map without repeating the both the sides in declaration
function addInversionInMap(op, opInverted){
inverted[op] = opInverted;
inverted[opInverted] = op;
}
//on document ready adds the click handler to every .buttonfunction elements
document.addEventListener("DOMContentLoaded", function() {
addClickHandlerToButtonsFunction();
});
//adds the handler for click event on .buttonfunction
function addClickHandlerToButtonsFunction(){
let btns = Object.values(document.getElementsByClassName('buttonfunction'));
for(let btn of btns){
btn.addEventListener('click', invertValue);
}
}
//return the inverted operator based on the inverted map
//(or return the operator as is if there's no way to invert)
function getInvert(operator){
if(inverted.hasOwnProperty(operator))
return inverted[operator];
else
return operator;
}
//inverts the value of the element whose id is declared in the data-target attribvute
//of the button that triggered the click event (such element should be input type text)
function invertValue(){
let contents = window.event.target;
if (contents.className == "buttonfunction") {
if (invert == true) {
let targetId = contents.getAttribute('data-target');
let target = document.getElementById(targetId);
//I'm using value so I expect the element to be input type text
target.value = getInvert(target.value);
}
}
}
button.buttonfunction{
cursor: pointer;
}
<input id="input" type="text"></input>
<button type="button" class="buttonfunction" data-target="input">Invert</button>
我想转换 Javascript 中的数学运算。例如给定一个“-”,它应该被转换为一个“+”,“*”-“/”等等。
我现在的代码是switch case,执行起来真的很慢:
if (contents.className == "buttonfunction") {
if (invert == true) {
switch (contents.innerHTML) {
case "+":
contents.innerHTML = "-";
break;
case "-":
contents.innerHTML = "+";
break;
case "*":
contents.innerHTML = "/";
break;
case "/":
contents.innerHTML = "*";
break;
}
}
document.body.appendChild(contents);
}
这个问题有better/faster解决方案吗?
性能可以忽略不计,但对于将一个事物映射到另一个事物的操作,table-driven 方法在较长的 运行 中通常更易于维护:
const inverseOperations = {
'+': '-',
'-': '+',
'/': '*',
'*': '/',
};
if (contents.className == "buttonfunction") {
const operation = contents.innerHTML
if (invert == true && inverseOperations[operation]) {
contents.innerHTML = inverseOperations[operation];
}
document.body.appendChild(contents);
}
我添加了一些上下文来制作一个 运行 示例。
顺便说一句,这里使用的方法是反转规则映射,替换您在 switch 语句中使用的逻辑:
let invert = true;
//granular map of pairs declaring the inverse of each operator
//it could be declared inline here but it could be also fed with the addInversionInMap
let inverted = {}; //{ '+' : '-', '-' : '+', '*' : '/', '/' : '*'}
addInversionInMap('+','-');
addInversionInMap('*','/');
//feeds the inverted map without repeating the both the sides in declaration
function addInversionInMap(op, opInverted){
inverted[op] = opInverted;
inverted[opInverted] = op;
}
//on document ready adds the click handler to every .buttonfunction elements
document.addEventListener("DOMContentLoaded", function() {
addClickHandlerToButtonsFunction();
});
//adds the handler for click event on .buttonfunction
function addClickHandlerToButtonsFunction(){
let btns = Object.values(document.getElementsByClassName('buttonfunction'));
for(let btn of btns){
btn.addEventListener('click', invertValue);
}
}
//return the inverted operator based on the inverted map
//(or return the operator as is if there's no way to invert)
function getInvert(operator){
if(inverted.hasOwnProperty(operator))
return inverted[operator];
else
return operator;
}
//inverts the value of the element whose id is declared in the data-target attribvute
//of the button that triggered the click event (such element should be input type text)
function invertValue(){
let contents = window.event.target;
if (contents.className == "buttonfunction") {
if (invert == true) {
let targetId = contents.getAttribute('data-target');
let target = document.getElementById(targetId);
//I'm using value so I expect the element to be input type text
target.value = getInvert(target.value);
}
}
}
button.buttonfunction{
cursor: pointer;
}
<input id="input" type="text"></input>
<button type="button" class="buttonfunction" data-target="input">Invert</button>