【问题标题】:Looping through array in if statement to check if all values pass在 if 语句中循环遍历数组以检查是否所有值都通过
【发布时间】:2017-04-17 21:33:54
【问题描述】:

我有一个变量“fieldCount”,它等于 5(我拥有的字段数)。如何在不具体说明每个索引的情况下写出以下内容:

if (
   fields[0].checkValidity() && fields[1].checkValidity() && fields[2].checkValidity()
   && fields[3].checkValidity() && fields[4].checkValidity()
) {
    fieldsPass = true;
}

【问题讨论】:

  • 请看我的回答,你可能错过了。我相信它可能对您有用(请注意,我推荐使用 everysome 方法,因为它们可以更清楚地向下一个开发人员表达您的意图。

标签: javascript arrays for-loop checkvalidity


【解决方案1】:

您可以使用循环,或一些相当标准的内置浏览器功能。

循环

以下是使用循环的方法。这应该是最快的代码,但您可能不需要最快的代码,除非您要检查大量项目的大量字段。我建议改为"correct, clear, concise, fast" 优先级,因此认为您应该从内置浏览器功能开始。但这里仅供参考:

var fieldsPass = true;
var i, l = fields.length;
for (i = 0; i < l; i += 1) {
   if (fields[i].checkValidity()) continue;
   fieldsPass = false;
   break;
}

请注意,在循环外声明i 变量并在循环外捕获字段长度是可选的。

我第一次这样做是因为很多人不知道提升,而且for (var i ... 不会创建仅在for 循环内可用的变量,这与在函数的顶部,这种行为可能会导致错误。

我出于习惯而做的第二个,尽管正如我所说,您可以将它放在循环检查中。 See this discussion。如果您确实使用循环方法,您可能正在寻找更好的性能,因此可能希望使用捕获的长度方式以获得最佳性能。 (如果它真的那么重要,你可以使用var i = fields.length; while (i--) { } 方法。)

浏览器函数数组.Every

​​>

您可以使用Array.prototype.every()(来自 ECMAScript 2015 第 6 版):

Mozilla Developer Network

every() 方法测试数组中的所有元素是否通过提供的函数实现的测试。

fieldsPass = fields.every(function(field) {
   return field.checkValidity();
});

当传入的函数在数组中的每个项目上运行时,它返回true,为所有这些项目返回true。如果任何一个返回false,它就会停止并返回false。在某些语言中,如果您熟悉的话,他们将相同的概念称为 all

或者,最好只声明一次checkValidity 函数,而不是将它放在每个字段上。这可能是不可能的,这取决于您如何实现它(也许它可以访问私有变量?)。请注意,您提供的回调函数的第一个参数(请参阅上面链接中的文档)是迭代的​​currentValue,即您要检查的字段。如果您的函数看起来像这样,它将起作用:

function checkValidity(field) { /* check validity */ }

fieldsPass = fields.every(checkValidity);

浏览器函数数组.Some

您也可以使用Array.prototype.some()(来自 ECMAScript 2015 第 6 版):

Mozilla Developer Network

some() 方法测试数组中的某个元素是否通过了提供的函数实现的测试。

fieldsPass = !fields.some(function(field) {
   return !field.checkValidity();
});

请注意,它基本上只是 every 的倒数,因为“ALL VALID”与“NOT (ANY INVALID)”相同。它只是意味着它检查数组中传递函数的任何一项,如果是,则返回true。在某些语言中,他们将相同的概念称为 any,如果您熟悉的话。

一般浏览器兼容性说明

请注意,对于这两个功能,浏览器兼容性非常好。如果您不关心版本 9 以下的 IE,那么您非常安全。如果你这样做了,那么你会想要使用上面链接的 MDN 页面上提供的 polyfill。您可以将该代码包含在您的 javascript 文件的全局范围内,然后就可以在 IE 8 及更低版本中正常使用它。 (我说的是这样开始的代码块:)

if (!Array.prototype.every) {
   Array.prototype.every = function(callbackfn, thisArg) {
   ...
}

【讨论】:

  • 可能是我找到的最好的解释之一!谢谢
【解决方案2】:

你有一个字段数组,你想迭代它们,并在每个字段上调用一个有效性检查方法。只有当它们都通过时,标志 fieldsPass 才会是 true

这正是Array#every 的行为。根据 MDN:

every() 方法测试数组中的所有元素是否通过 由提供的函数实现的测试。


使用Array.every 在每个字段上调用checkValidity()。如果所有字段都有效,则结果将为true。如果一个字段失败checkValidity(),循环将立即返回false,而不检查其他字段。

var fieldPass = fields.every(function(field) {
  return field.checkValidity();
})

【讨论】:

  • 感谢您的链接。不过,关于它在哪些浏览器/版本中可用,以及那些没有它的浏览器的 MDN polyfill 怎么样?
  • @ErikE 似乎太过分了,不是吗?几乎所有的浏览器都有every,如果你发现自己需要一个 polyfill,很容易搜索或自己编写一个。
【解决方案3】:

如你所说,使用loop.

var fieldsPass = true;
for (var i = 0; i < fields.length; i++) {
  // Exit early if one of them fails
  if (!fields[i].checkValidity()) {
    fieldsPass = false;
    break;
  }
}

【讨论】:

    【解决方案4】:

    您可以使用.some() 方法并反转逻辑以判断是否全部通过:

    var allPassed = !fields.some(function (field) {
      return !field.checkValidity();
    });
    

    【讨论】:

    • 浏览器兼容性表和 polyfill 在 MDN 链接上。我也应该引用 ECMAScript 规范吗?
    • @ErikE 25,000 名用户发布
    • @ErikE 煽动和吹毛求疵只是为了煽动和吹毛求疵,然后因为人们为自己辩护而取笑人们,这基本上是拖钓的定义......
    • 我没有激动,也没有吹毛求疵。这就是有趣的事情。我试图帮助你做出更好的回答。
    • 实际上,我很想看到来自 ECMAScript 2015 语言规范 @mhodges 的引用。我认为这肯定会放大这个答案的有用性,这当然取决于引用的相关性。
    【解决方案5】:

    你可以这样做:

    fieldsPass = true;
    for (i = 0; i < fieldCount; i++)
    {
         if(!fields[i].checkValidity())
         {
              fieldsPass = false;
              break;
         }
    }
    

    【讨论】:

    • 是的,你是对的,休息一下;在fieldsPass = false之后;应该做的工作。
    • 嗯,JordanBarber 说他在代码的某处有一个“fieldCount”变量(可能是硬编码的),所以我想用它来代替长度计算。
    • 真的!我错过了。删除评论。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2017-07-24
    • 2011-09-05
    • 2018-06-26
    • 1970-01-01
    • 1970-01-01
    • 2016-05-30
    • 1970-01-01
    相关资源
    最近更新 更多