【问题标题】:How to prevent Zero from appearing in Calculator?如何防止零出现在计算器中?
【发布时间】:2018-04-29 01:26:36
【问题描述】:

我正在编写一个 FreeCodeCamp 计算器。我现在正在处理的问题是重复运算符。例如,如果我按“5”然后按“+”,但改变主意并按“-”,则历史记录区域应显示“5-”而不是“5+”。但是,使用我的代码,它显示“5+0-”。因此,我意识到我也需要解决“零”问题。

我想为“零”问题做的列表是:

  1. 如果按“0”,则允许它出现在历史区域中。例如,如果有人按“0”,然后按运算符,它应该在历史区域中显示为“0-”。
  2. 否则,如果有人先按运算符而不输入任何数字,则停止此方法

这是我来自 Codepen 的代码:

$(document).ready(function() {
  
  var mainMath = "0";
  var subMath = "0";
  var finalset = "";
  var subMatharray = [];
  var oppArray = [];
  var equalPressed = false;
  var prevKey = "";
  update();
  
  $("button").click(function(){
    calculate($(this).attr("value"));
  });
  
  function calculate(keyitem) {
    console.log("buttonpress: " + keyitem);
    switch(keyitem) {
      case "clear":
        clearScreen();
        break;
      case "%":
        percentageScreen();
        break;
      case "/":
      case "*":
      case "+":
      case "-":
        addOperator(keyitem);
        break;
      case "plusminus":
        plusminusScreen();
        break;
      case "0":
      case "1":
      case "2":
      case "3":
      case "4":
      case "5":
      case "6":
      case "7":
      case "8":
      case "9":
        addNumber(keyitem);
        break;
      case ".":
        addDecimal(keyitem);
        break;
      case "=":
        solveEqual(keyitem);
        break;
    }
    update();
    };
 
  function clearScreen() {
     mainMath = "0";
     subMath = "0";
     prevKey = "";
     subMatharray = [];
     oppArray = [];
    if(mainMath.length > 0){
      $(".entry").css("font-size", "4em");
    }
    console.log("clearMain: " + mainMath);
    console.log("clearSub: " + subMath);
  };
  
  function plusminusScreen() {
     mainMath = -1 * mainMath;
    finalset = mainMath;
    console.log("plusminusMain: " + mainMath);
    console.log("plusminusFinal: " + finalset);
  };
  
  function addNumber(keyitem) {
    if (mainMath == "0"){
      mainMath = keyitem/*mainMath.replace("0", keyitem);*/
      finalset = mainMath;
      return;
      console.log("addedMainZero: " + mainMath);
      console.log("addedFinalZero: " + finalset);
    }
    if (equalPressed == true){
      mainMath = keyitem;
      subMath = "0";
      subMatharray = [];
      equalPressed = false;
      console.log("addNumberEqualmain: " + mainMath);
    }
    mainMath+=keyitem;
    finalset = mainMath;
    
    console.log("addedMain: " + mainMath);
    console.log("addedFinalset: " + finalset);
    console.log("addedarray: " + subMatharray);
    
    if(mainMath.length > 8){
      $(".entry").css("font-size", "1.5em");
    }
    
  };
  
  function addOperator(keyitem){
    
    if (equalPressed == true){
      subMatharray = [];
      equalPressed = false;
      console.log("addOpEqualarray: " + subMatharray);
    }
    /*if (mainMath == "0" && finalset !== "0"){
      mainMath = "0";
      subMatharray.push(keyitem);
      return;
      console.log("addedMainZero: " + mainMath);
      console.log("addedFinalZero: " + finalset);
    }*/
    
    oppArray.push(keyitem);
    console.log("addOpArray: " + oppArray);
    var opkeyitem = "";
    
    subMatharray.push(mainMath);
    prevKey = "numbertest";
    
    if(prevKey == "numbertest") {
      subMatharray.push(keyitem);
      prevKey = "operatortest";
      console.log("addOpArraySubArrayElse: " + subMatharray);
      console.log("addOpArrayPrevKeyElse: " + prevKey);
    } /*else if (oppArray.length > 1 && prevKey == "operatortest") {
      subMatharray.pop();
      subMatharray.push("droubletest");
      oppArray = [];
      console.log("addOpArraySubArray: " + subMatharray);
      console.log("addOpArrayPrevKey: " + prevKey);
    } /*else if(prevKey == "numbertest") {
      subMatharray.push(keyitem);
      prevKey = "operatortest";
      console.log("addOpArraySubArrayElse: " + subMatharray);
      console.log("addOpArrayPrevKeyElse: " + prevKey);
    }*/
    
    subMath = subMatharray.join("");
    mainMath = "0";
    prevKey = keyitem;
    console.log("addOpSub: " + subMath);
    console.log("addOpMain: " + mainMath);
    console.log("addOpMainarray: " + subMatharray);
    console.log("equaltrueTest: " + equalPressed);
  };
  
  function addDecimal(keyitem){
    if (mainMath.indexOf(keyitem) === -1){
      if(mainMath == "0") {
        mainMath = "0" + keyitem;
        return;
      }
    } else {
        return;
      }
    addNumber(keyitem);
  };
  
  function solveEqual(keyitem) {
    subMatharray.push(finalset);
    subMath = subMatharray.join("");
    mainMath = eval(subMath);
    console.log("solveEqualresult: " + mainMath);
    console.log("solveEqualhistory: " + subMath);
    console.log("solveEqualarray: " + subMatharray);
    var finalresult = mainMath.toString();
    if(finalresult.length > 8){
      $(".entry").css("font-size", "1.5em");
    }
    equalPressed = true;
  };
  
  function update(){
  $("#answer").html(mainMath);
  $("#history").html(subMath);
};
  
});

/*Problems
2. I need to work on percentage button soon...
3. fix the problem if someone click an operator more than one.
*/
@import url('https://fonts.googleapis.com/css?family=Roboto:300,400');
h1, h2, h3, p {
  font-family: 'Roboto', sans-serif;
}
html, body{
  height:100%;
  margin: 0;
  background-color: #ffffff;
}
.wrapper {
  width: 100%;
  height: 100%;
  position: relative;
  display:flex;
  flex-direction:column;
  justify-content:center;
  align-items:center;
  background-repeat: no-repeat;
    background-size: cover;
  background-position: center center;
  padding: 160px 0;
}
.calculatorbox {
  width: 300px;
  margin: 0 auto;
  border: 1px solid #000000;
}
.calheader {
  text-align: center;
}
.calwindow {
  background: #000000;
  position: relative;
  display: -webkit-box;
  display: -moz-box;
  display: -ms-flexbox;
  display: -webkit-flex;
  display: flex;
   -webkit-flex-direction: column; /* Safari */
  flex-direction:         column;
  -webkit-justify-content: flex-end;
  justify-content: flex-end;
  -webkit-align-items: flex-end;
  align-items: flex-end;
  padding: 10px 0;
  box-sizing: border-box;
}
.entry {
  font-size: 4em;
  display: block;
  line-height: 1em;
}
.entryhistory {
  font-size: 1em;
  letter-spacing: 2px;
  padding-right: 5px;
}
.entry p, .entryhistory p {
  margin: 0;
  color: #ffffff;
}
sup {
  top: -0.5em;
}
 
sub {
  bottom: -0em;
}
.row {
  clear: both;
  width: 100%;
  display: flex;
}
button {
  display: inline-block;
  border: none;
  padding: 0;
  outline: none;
  cursor: pointer;
}
.key {
  width: 75px;
  height: 70px;
  font-size: 22px;
  border-top: 1px solid rgba(0, 0, 0, 0.3);
  border-right: 1px solid rgba(0, 0, 0, 0.3);
  box-sizing: border-box;
}
.key.btnspan {
  width: 150px;
}
.key.topcolor {
  background: #d9d9d9;
}
.key.orange {
  background: #ff8c00;
  color: #ffffff;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class="wrapper">
  <div class="calheader">
      <h2>Simple Calculator</h2>
    </div>
  <div class="calculatorbox">
    <div class="calwindow">
      <!-- ENTRY BOX -->
      <div class="entry">
        <p id="answer"></p>
      </div>
      <div class="entryhistory">
        <p id="history"></p>
      </div>
    </div>
    <!-- BUTTONS -->
    <div class="calbuttons">
      <div class="row">
        <button class="key topcolor" value="clear">C</button>
        <button class="key topcolor" value="plusminus"><sup>+</sup>/<sub>−</sub></button>
        <button class="key topcolor" value="%">%</button>
        <button class="key orange" value="/">÷</button>
      </div>
      <div class="row">
        <button class="key" value="7">7</button>
        <button class="key" value="8">8</button>
        <button class="key" value="9">9</button>
        <button class="key orange" value="*">×</button>
      </div>
      <div class="row">
        <button class="key" value="4">4</button>
        <button class="key" value="5">5</button>
        <button class="key" value="6">6</button>
        <button class="key orange" value="-">−</button>
      </div>
      <div class="row">
        <button class="key" value="1">1</button>
        <button class="key" value="2">2</button>
        <button class="key" value="3">3</button>
        <button class="key orange" value="+">+</button>
      </div>
      <div class="row">
        <button class="key btnspan" value="0">0</button>
        <button class="key" value=".">.</button>
        <button class="key orange" value="=">=</button>
      </div>
    </div>
  </div>
</div>

所有动作都发生在function addOperator(keyitem)。我试图解决“零”问题,但我将其注释掉,以便您可以完全了解我在说什么。这是我注释掉的代码。

if (mainMath == "0" && finalset !== "0"){
      mainMath = "0";
      subMatharray.push(keyitem);
      return;
      console.log("addedMainZero: " + mainMath);
      console.log("addedFinalZero: " + finalset);
    }

我期待任何可以帮助我解决“零”问题的建议或代码解决方案。

【问题讨论】:

  • 问题出在 addOperator 函数中,您将 mainMath 推入 subMatharray,并且在 addOperator 函数结束时将 mainMath 设置为 0。所以:我们有 addOperator 第一次单击 -> 添加 mainMath,这恰好是正确的 -> 将 mainMath 设置为 0 -> addOperator 第二次单击 -> 添加 mainMath(为 0)以及运算符 -> 将 mainMath 设置为 0。跨度>

标签: javascript jquery calculator


【解决方案1】:

我会重新考虑从“0”到 null 的初始值,以便能够拆分零逻辑和初始逻辑:

var mainMath = null;
// ...

function clearScreen() {
  mainMath = null;
  // ...
}

function addNumber(keyitem) {
  if (mainMath === null) { 
    mainMath = "0"; //hacky, I know, this requires more deep refactoring
  }
  // ...
}

function addOperator(keyitem){
  if(mainMath === null) {
    return; // this is the main point
  }
  // ...    
  mainMath = null;
  // ...
}

$("#answer").html(mainMath === null ? "0" : mainMath);

这只是一个想法,应该改进方法,但您可以在codepen fork 上尝试临时结果。

【讨论】:

  • @KristinaBressler 如果要显示它,只需在值为 null 时显示“0”。我会更新答案和分叉
  • 清屏怎么样?我需要正确处理这个问题,以便我可以重复测试计算器
  • 没关系,我想我通过将您添加到函数 addNumber 的内容添加到清除函数 if (mainMath === null){ mainMath = "0"; } 来修复它
  • 我的代码快到了。您可以在codepen.io/kikibres/pen/vWJxBW 查看我当前的代码。在我的调整和您的帮助下,如果首先输入的运算符没有任何数字,我就能阻止它们。
  • if (["/", "*", "+", "-"].indexOf(keyitem) &gt; -1 &amp;&amp; ["/", "*", "+", "-"].indexOf(prevKey) &gt; -1) { oppArray.shift(); opkeyitem = oppArray.toString(); subMatharray.pop(); subMatharray.push(opkeyitem); oppArray = []; prevKey = null; } else if(prevKey == null) { subMatharray.push(keyitem); prevKey = keyitem; }
【解决方案2】:

在您的“addOperator”函数中,您只需要一个简单的 if 语句,检查字符串中的最后一个字符是否是运算符。如果是则交换它,如果不是则添加给定的运算符

编辑:

我仔细查看了代码,看起来它比单个 if 语句要复杂一些,并且需要进行大量重写。我所能提供的只是一种不同的方式来存储你的价值观。

我建议在按下按钮后立即存储实际按钮按下的数组,然后在您的各个按钮功能中修改该列表,然后从该列表中生成您正在显示的内容。例如,如果用户按 1、+、2、3、-、+、=,则数组将如下所示:

[] -> []

[1] -> [1]

[1,+] -> [1,+]

[1,+,2] -> [1,+,2]

[1,+,2,3] -> [1,+,23] // 通过 addNumber 检查,连接数字

[1,+,23,-] -> [1,+,23,-]

[1,+,23,-,+] -> [1,+,23,+] // 由 addOperator 检查,交换操作符

[1,+,23,-,+,=] -> [] // 由solveEqual检查,求解然后清空数组

将其作为全局变量将允许您的按钮函数修改数组,而不是像当前那样从函数中推送元素,这样做的好处是您可以'不要像 null 或操作符那样推送不应该推送的元素

【讨论】:

  • 请阅读@Tyler Dahle 的评论。这就是为什么我不能简单地按照你的建议去做的原因......以及我需要解决“零”问题的原因
  • 您必须区分实际按下某个键的时间和从显示屏上抓取的时间。据我了解,您只是从当前显示的内容中获取,而不是最后按下的键是什么?
  • 跟进最后一条评论,看起来您的 subMatharray 将能够做到这一点,因为它列出了所有的按钮按下。您只需要检查最后一个索引以查看它是否是操作符键、实际的零/数字,或者操作符是否是按下的第一个按钮(然后您将使用零)
  • 你能写出解决方案吗?
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2014-04-18
  • 1970-01-01
  • 1970-01-01
  • 2021-07-30
相关资源
最近更新 更多