where / when /为什么第一个数组元素掉线?

时间:2017-02-16 03:44:36

标签: javascript

我的任务是有一个接受用户输入的文本框,将该输入推送到数组中,然后根据复选框的状态检查硬编码数组,以评估用户输入元素是否与硬编码匹配数组元素。

在基本情况下,字符串必须完全匹配(基于区分大小写),我的代码与匹配的单词一致,并忽略不匹配的单词。我将匹配的单词添加到字符串中,然后在警报中显示该字符串。

但是:在第二种情况下,字符串旨在忽略区分大小写(因此用户可以输入大小写的任意组合),显示匹配名称列表的警报总是丢弃输入的第一个字。用户输入文本框。区分大小写逻辑似乎工作正常 - 问题是其中一个单词被删除。

这是我的代码首先是HTML shell



function process() {

//create string to store user input
var s = document.getElementById("inputTextBox").value;

//testing text area to display captured input
document.getElementById("textArea").value = s;

//create array to store user input
var inputArray = [];

//create array of names to check user input against
var namesArray = ["John", "Bill", "Mary", "Ted", "Roger"];

//split the string by spaces
var input = s.split(" ");

//put the split string into the inputArray
inputArray = s.split(" ");

//determine length of arrays
var inputArrayLength = inputArray.length;
var nameArrayLength = namesArray.length;

//create string to hold matched names
var matchedNames = "";

for(var i = 0; i < inputArrayLength; i++)
{
    //set current name string to current array element
    currName = inputArray[i];

    //first determine if the checkbox IS checked
    if ((document.getElementById("checkBox").checked) == true)
    {
        //if it is checked, determine if currName == name in namesArray
        if (currName == 'John' || currName == 'Bill' || currName == 'Mary' || currName == 'Ted' || currName == 'Roger')
        {
            matchedNames = matchedNames.concat(currName + " ");
        }}

    //if it is NOT checked
    else if ((document.getElementById("checkBox").checked) == false)
    {
        //traverse array and toLowerCase all elements
        for (var j = 0; j < inputArrayLength; j++)
        {
            inputArray[j] = inputArray[j].toLowerCase();
        }

        //then determine if toLowerCase string is present in array
        if (currName == 'john' || currName == 'bill' || currName == 'mary' || currName == 'ted' || currName == 'roger')
        {
            matchedNames = matchedNames.concat(currName + " ");
        }
    }
}

document.getElementById("textArea").value = matchedNames;

//alert matched names
alert("Matched Names: " + matchedNames + ".");
}
&#13;
<label>Please enter a series of first names, separated by spaces</label>
<br />
<input id="inputTextBox" type="text" name="textBox1" style="width: 200px;"/>
<br />
<label><input id="checkBox" type="checkbox" name="checkbox1" />toggle case sensitivity</label>
<br />
<input id="Button1" type="button" value="Process" onclick="process();"/>
<br />
<textarea id="textArea" name="textArea1" rows="2" cols="1" style="width: 400px;"></textarea>
&#13;
&#13;
&#13;

我知道有很多风格问题(糟糕的名字),一些严重的冗余,并且这可能会在逻辑上收紧,以减少使用更少的线等。

3 个答案:

答案 0 :(得分:1)

  

这可能会在逻辑上收紧,以减少使用

逻辑基本上是你问题的根源。你有一个循环来测试每个currName。在循环内部,检查是否选中了复选框,如果不是,则输入数组小写;但是在小写之前,第一个currName被取出了。因此,如果您输入John Mary Bill,则会比较非小写的John,然后是小写的marybill。非小写的John显然不等于john。此外,整个数组的小写更适用于数组的每个元素,这会给代码增加不必要的指数复杂性(即不必要的低效率)。

在开始时(循环之前,分割之前,偶数)只输入小写输入字符串要容易得多:

if (caseSensitive) {
  s = s.toLowerCase();
}
var input = s.split(" ");

或者至少要将每个currName小写为从数组中删除:

var origCurrName = inputArray[i];
var currName = origCurrName;
if (caseSensitive) {
  currName = currName.toLowerCase();
}

进一步说明:

  • 你不必测试某件事是否true; if条件将触发表达式为真值(truefalse,而else if不是。)
  • 如果您知道只有两个选项(如真实和虚假,已选中和未选中),则无需使用else,只需input就可以了
  • 您永远不会使用变量caseSensitive
  • 在循环之前使用var caseSensitive...更有效率,并且可以提高你的代码清晰度...如果只有你会使用它:)
编辑:Derp,在滚动中,我误认为Phil的sourceanalyzer -b test -clean sourceanalyzer -b test -Xmx6G -verbose -debug -logfile vs_translate.txt "C:\Program Files (x86)\Microsoft Visual Studio 14.0\Common7\IDE\devenv.exe" NewWebForms.sln /REBUILD Debug sourceanalyzer -b test -show-files > vs_files.txt sourceanalyzer -b test -show-build-warnings > vs_warnings.txt sourceanalyzer -b test -verbose -debug -logfile vs_scanlog.txt -scan -f vs_scan.fpr fprutility -information -categoryIssueCounts -project vs_scan.fpr 行为你的。向Phil和OP道歉。

答案 1 :(得分:1)

在第二种情况下的匹配过程中,您尚未将currName转换为小写。 所以你可以currName.toLowerCase() == "john"等等......

答案 2 :(得分:0)

它不起作用的原因是你在循环的第一次迭代中将inputArray转换为小写但你不能转换仍然是原始值的currName

在后续迭代中,currName从现在小写的数组中拉出,以便它们正确匹配。

无论如何,使用Array.prototype.filterArray.prototype.indexOf

这是一个更简单的方法

//create array of names to check user input against
var namesArray = ["John", "Bill", "Mary", "Ted", "Roger"];
var lowerCaseNamesArray = namesArray.map(name => name.toLowerCase())

function process() {

  //create string to store user input
  var s = document.getElementById("inputTextBox").value;

  // are we doing case-sensitive checks
  var caseSensitive = document.getElementById("checkBox").checked;
  if (!caseSensitive) {
    s = s.toLowerCase();
  }

  //create array to store user input
  var inputArray = s.split(" ");
  
  // which array should we check?
  var checkArray = caseSensitive ? namesArray : lowerCaseNamesArray;
  
  var matchedNames = inputArray.filter(function(currName) {
    return checkArray.indexOf(nameToCheck) !== -1;
  });

  document.getElementById("textArea").value = matchedNames.join(' ');
}
<label>Please enter a series of first names, separated by spaces</label>
<br />
<input id="inputTextBox" type="text" name="textBox1" style="width: 200px;" />
<br />
<label><input id="checkBox" type="checkbox" name="checkbox1" />toggle case sensitivity</label>
<br />
<input id="Button1" type="button" value="Process" onclick="process();" />
<br />
<textarea id="textArea" name="textArea1" rows="2" cols="1" style="width: 400px;"></textarea>