【问题标题】:Check if input is between two values (multiple conditions)检查输入是否在两个值之间(多个条件)
【发布时间】:2016-10-19 20:27:17
【问题描述】:

我正在做一个项目,我需要读取不同格式的数字,并根据用户输入检查这些数字。在某些情况下,这将是一个类似“8800-9000”的区间,在某些情况下,它将是一个 4 位数字,在某些情况下是一个 5 位数字。

数组如下所示:

var testArray = [
{
    "label": "Nordea",
    "value": ["1100-1199", "1400-2099", "3000-3399", "3410-4999"]
},
{
    "label": "Swedbank",
    "value": ["7000-7120", "7123-8104", "8106-8999"]
},
{
    "label": "Sparbanken Nord",
    "value": "8264"
},
{
    "label": "Sparbanken i Enköping",
    "value": ["7121-7122", "8305-5"]
}];

我已经制作了一个巨大的嵌套 if-messs,效果还不错。我唯一的问题是它在找到匹配项时不会中断。如果我输入“8305-5”,它将在 2 个不同的对象属性数组中找到匹配项。我设计的“between”功能错了吗?

我还可以搜索比间隔大得多的数字并且仍然得到匹配。间隔“3410 - 3999”在一个数组中,如果我搜索“39999”,它仍然会得到匹配。

非常感谢所有帮助!

我遍历数组中的所有对象,如果 value-property 是一个数组,我将检查每个元素的长度,看看我应该匹配“between”-value 还是直接匹配“===” .

如果它不是一个数组,我尝试一个简单的匹配。

function searchForClearing() {

  var userInput = document.getElementById("clearingnummerTextBox").value;

  for (var i in testArray) {
    var currentObject = testArray[i];

    if (Array.isArray(currentObject.value)) {

      for (i = 0; i < currentObject.value.length; i++) {

        if (currentObject.value[i].length === 9) {

          var firstInterval = currentObject.value[i].split('-')[0];

          var lastInterval = currentObject.value[i].split('-')[1];

          if (userInput >= firstInterval && userInput <= lastInterval) {
            console.log("Inmatat: " + userInput + " " + "Träff på: " + currentObject.value);
            document.getElementById("bankResult").innerHTML = currentObject.label;
            console.log("Sökte mellan intervallen: " + firstInterval + " - " + lastInterval);

            console.log("9 teckens sök");
          }

        } else if (currentObject.value[i].length === 6) {

          if (userInput == currentObject.value[i]) {
            console.log("Inmatat: " + userInput + " " + "Träff på: " + currentObject.value);
            document.getElementById("bankResult").innerHTML = currentObject.label;
            console.log("Sökte mellan intervallen: " + firstInterval + " - " + lastInterval);
            console.log("6 teckens sök");
          }
        }
      }
    } else {
      if (currentObject.value.length === 9) {

        var firstInterval = currentObject.value.split('-')[0];
        var lastInterval = currentObject.value.split('-')[1];

        if (userInput >= firstInterval && userInput <= lastInterval) {
          console.log("Inmatat: " + userInput + " " + "Träff på: " + currentObject.label);
          document.getElementById("bankResult").innerHTML = currentObject.label;
          console.log("Sökte mellan intervallen: " + firstInterval + " - " + lastInterval);
          return true;
        }

      } else if (currentObject.value.length === 4) {

        if (userInput == currentObject.value) {
          console.log("Träff på clearingnummer som inte var i en array: " + userInput + " " + currentObject.label);
          document.getElementById("bankResult").innerHTML = currentObject.label;
          return true;
        }

      }

    }
  }
}

【问题讨论】:

    标签: javascript arrays loops


    【解决方案1】:

    “39999”返回true 的原因即使它超出范围是因为JS 中的字符串是比较lexographically

    "39999" < "4999" // true
     39999  <  4999  // false
    

    在进行比较之前,您需要使用parseInt 之类的方式将字符串转换为数字。

    就减少一些嵌套的if 混乱而言,此示例中您最好的两个朋友是Array.prototype.findArray.prototype.some

    findsome 都迭代一个数组,为每个元素调用一个函数。

    • find:如果该函数返回truefind 将停止迭代并返回当前元素。您可以使用它在您的testArray 中查找其value 等于用户输入或包含在一个范围内的对象。

    • some:如果该函数返回truesome 将停止迭代并返回true。当testArray 值是一个数组时,您可以使用它来检查用户输入是否在至少一个范围内。我们使用some 而不是另一个find,因为我们只想检查数组中是否包含某些内容,而不关心实际取回它。

    以下是使用findsome 编写函数的方法:

    function findTestObject(input) {
    
      // iterate over the test array and 
      // stop as soon we found a match 
      // (as the passed function returns true)
      return testArray.find(function (testObj) {
        var value = testObj.value;
    
        // if current value is an array of ranges
        // check if userInput is within at least one of the ranges
        if (Array.isArray(value)) {
          return value.some(function (range) {
            // split the current range into min and max and compare with user input
            var rangeData = range.split('-');
            return parseInt(rangeData[0]) <= input && input <= parseInt(rangeData[1]);
          });
        } 
        // otherwise do a direct comparison
        else {
          return value === input;
        }
      });
    }
    

    此函数将返回来自testArray 且其值与用户输入匹配的第一个对象,或者返回undefined

    这是一个完整的例子:

    var testArray = [{
      "label": "Nordea",
      "value": ["1100-1199", "1400-2099", "3000-3399", "3410-4999"]
    }, {
      "label": "Swedbank",
      "value": ["7000-7120", "7123-8104", "8106-8999"]
    }, {
      "label": "Sparbanken Nord",
      "value": "8264"
    }, {
      "label": "Sparbanken i Enköping",
      "value": ["7121-7122", "8305-5"]
    }];
    
    function findTestObject(input) {
      return testArray.find(function (testObj) {
        var value = testObj.value;
    
        if (Array.isArray(value)) {
          return value.some(function (range) {
            var rangeData = range.split('-');
            return parseInt(rangeData[0]) <= input && input <= parseInt(rangeData[1]);
          });
        } else {
          return value === input;
        }
      });
    }
    
    function test() {
      var userInput = document.getElementById("input").value;
      var result = findTestObject(userInput);
      var label = result ? result.label : 'Not Found';
      document.getElementById("result").innerHTML = label;
    }
    <input id="input" placeholder="Enter something..."/>
    <button onclick="test()">Test</button>
    <br />
    Result: <div id="result"></div>

    注意:您的示例中存在不一致之处。除了在最后一个数组中,所有范围都按递增顺序(最小值,最大值),您有"8305-5"。 使用上面的代码,这个范围永远不会返回 true。

    解决此问题的一种方法是在比较之前始终按升序对范围数组进行排序。

    var rangeData = range.split('-').sort();
    

    有关示例和陷阱,请参阅 How to correctly sort array of integers

    【讨论】:

    • 非常感谢您的详尽回答!这向我解释了很多。我来自 C#,所以松散类型的语言对我来说真的很新。
    • 最后一个例子“8305-5”是一个真正的价值,这是我的问题之一。我还必须根据这个值检查用户输入。我检查了元素的长度是否为“6”,这似乎有效。
    • 不客气,伙计:)。至于 8305-5 部分,如果您无法更改接收到的数据,而不是检查硬编码的长度值,您可以调用 range.split('-').sort() 在比较之前始终按升序对最小/最大值进行排序,这样它会更通用。 See this question 示例
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2022-03-30
    • 1970-01-01
    • 2019-02-09
    • 2019-10-06
    • 2021-03-03
    • 2019-11-29
    • 1970-01-01
    相关资源
    最近更新 更多