【问题标题】:Check if all elements satisfy a condition with for-loop使用for循环检查所有元素是否满足条件
【发布时间】:2018-04-05 00:12:47
【问题描述】:

我基本上尝试使用以下代码检查所有输入字段是否有效:

 addData (input){

   var isValid = false;    

   for (var i = 0, ii = input.length; i < ii; ++i) {          

      if ($('#' + input[i].id).hasClass('valid')) {
          isValid = true;              
      }
   }

   if (isValid) {
     //do stuff
   }
 }

input.length 总共为 3,我想检查所有 3 个输入字段是否都有效。在我的示例中,它只检查最后一个输入元素。在related posts 中,我找不到使用 for 循环解决它的方法。有人可以帮忙吗?

感谢所有有用的答案:最后,我调整了 Máté Safranka 的答案:

var isValid = input.toArray().every(element => $('#' + element.id).hasClass('valid'))

使用 .toArray() 将 jQuery 对象转换为 Array >> see here 以获取更多信息。定义 truefalse 不是 不再需要了。

【问题讨论】:

  • 如果变量中已有输入,则无需使用其 ID 重新查找它们(它们可能没有 id),例如:if ($(input[i]).hasClass("valid")) {
  • var i = 0, ii = input.length; i &lt; ii; ++i 您使用的是i 还是ii
  • 您的代码确定any输入是否有效;如果其中至少一个是,则isValid 设置为true
  • @ScottMarcus 再看一遍,i 用于循环,ii 用于退出条件(这是一种非常规但有效的设置边界的方法)(非常规,因为有些人认为它是一个错误...)
  • @freedomn-m 这就是我问的原因。我没有说这是一个错误,但恕我直言,使用名称如此相似的两个变量是一个非常糟糕的主意。这是一个等待发生的错误。

标签: javascript jquery for-loop


【解决方案1】:

您永远不会将 isValid 设置为 false,因此只要至少有一个输入有效,结果就会有效。

最好交换真/假并检查任何无效的,例如:

addData (input){

 var isValid = true;    

 for (var i = 0, ii = input.length; i < ii; ++i) {          
   if (!$('#' + input[i].id).hasClass('valid')) {
      isValid = false;              
   }
 }

 if (isValid) {
  //do stuff
 }
}

注意:使用循环还有其他选择,但这是为了回答在 OPs 问题中修复循环的明确问题。

【讨论】:

  • 由于我要求使用for循环的解决方案,所以这个答案是正确的。但是,我将我的最终解决方案附加到我的问题中。谢谢!
【解决方案2】:

你错了。您假设在元素有效之前无效。并且您应该假设有效,直到一个元素无效:

addData (input){
   var isValid = true;    

   for (var i = 0, ii = input.length; i < ii; ++i) {          

      if (!($('#' + input[i].id).hasClass('valid'))) {
          isValid = false;              
      }
   }

   if (isValid) {
     //do stuff
   }
}

【讨论】:

    【解决方案3】:

    正如其他人所说,您需要先将isValid 设置为true,然后从第一个无效字段开始,将其设置为false 并打破循环。

    但如果 input 真的是一个数组,我会使用 input.every 代替:

    addData (input){
        if (input.every(function(element) { return $(element).hasClass('valid'); })) {
            // Do stuff
        }
    }
    

    Array#every 为数组中的项目调用回调,如果回调为所有项目返回真值,则返回 true,或者如果回调返回虚假值,则返回 false(并立即停止) .

    或者你可以使用 jQuery 的 filter:

    addData (input){
        if ($(input).filter(':not(.valid)').length === 0) {
            // Do stuff
        }
    }
    

    Array#every 如果可以使用 ES2015+ 箭头函数会更简洁:

    addData (input){
        if (input.every(element => $(element).hasClass('valid'))) {
            // Do stuff
        }
    }
    

    【讨论】:

      【解决方案4】:

      如果input是一个数组,可以使用.every()

      var isValid = input.every(it => $('#' + it.id).hasClass('valid'));
      

      如果input 不是数组,您可以使用Array.from() 将其转换为数组。

      https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/every

      注意: 正如 cmets 中所指出的,这适用于 IE10 及更高版本。大多数时候这应该不是问题(Windows 10 附带 IE11 和 Edge,理论上每个商业最终用户现在都应该升级),但值得注意的是,如果您必须支持旧平台。

      【讨论】:

      • 总是很高兴看到“新”功能,但值得注意的是浏览器支持,因为它一个问题:caniuse.com/#search=every(显示全部)(IE10+)
      • @freedomn-m 这就是为什么会有 polyfill 的原因 ;) 不要因为浏览器过时而退缩。
      • @str 同意,但我在这里看到很多问题,例如“此代码不起作用=&gt; ...”)...... 500 cmets 后:“哦,是的,我我正在使用 IE6"... :)
      • 我调整了你的代码,现在它工作正常:我设置了 var isValid = true; if (!input.toArray().every(element =&gt; $('#' + element.id).hasClass('valid'))) { isValid = false; }
      • 这不是必需的,every() 如果所有元素都满足条件,则返回true,如果不满足条件,则返回false,这就是isValid 的值所需要的.所以它应该只适用于var isValid = input.toArray().every(element =&gt; $('#' + element.id).hasClass('valid'));
      【解决方案5】:

      anding trueisValid (而不是直接分配 true)将使它成为第一个 false 值将使整个条件为 false。只需确保在循环之前以 isValid 开头为 true。

      isValid = true;
      
      // inside the loop
      
      isValid = isValid && true;
      

      【讨论】:

      • 因为isValidfalse 开头,所以该表达式永远不会是true
      • @Pointy 是的,我在你写之前就注意到了
      猜你喜欢
      • 2013-03-06
      • 1970-01-01
      • 2017-06-20
      • 1970-01-01
      • 1970-01-01
      • 2019-10-23
      • 2021-12-07
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多