【问题标题】:JavaScript - get array element fulfilling a conditionJavaScript - 获取满足条件的数组元素
【发布时间】:2011-04-16 04:28:48
【问题描述】:

我正在使用 W3C 学习 JavaScript,但我没有找到这个问题的答案。

我正在尝试对满足某些条件的数组元素进行一些操作。

除了在 for 循环中的数组元素上运行之外,还有其他方法吗? 可能类似于(在其他语言中):

foreach (object t in tArray)
   if (t follows some condition...) t++;

另一件事,有时我想使用元素的值,有时我想将其用作参考。语法有什么区别?

同样,我很乐意提供更多关于学习 JavaScript 的网站的建议。 谢谢

【问题讨论】:

标签: javascript arrays conditional-statements


【解决方案1】:

您可以在 JavaScript 中使用for ... in

for (var key in array) {
    if (/* some condition */) {
        // ...
    }
}

从 JavaScript 1.6 开始,您也可以使用它:

for each (var element in array) {
    // ...
}

这些主要是为了遍历对象属性。您应该考虑简单地使用您的for-loop。

编辑:您可以使用像 jQuery 这样的 JavaScript 框架来消除这些跨浏览器问题。试一试。它的$.each()-method 完成了这项工作。

【讨论】:

  • 没错,这些方法有效,但通常不推荐使用。原因是它还枚举了数组对象的其他属性(并且很多库都添加了此类属性),这会产生不可预知的结果。
  • @sje397:没错。为此,我强烈推荐 jQuery。它的$.each()-method 工作得非常好并且提供了闭包。由于 JavaScript 有函数作用域,这在你的循环中做很多事情时非常有用。
  • for...in 枚举的实际属性集是完全可以预测的,尽管它确实因浏览器而异。通常不可预测的是迭代顺序。对于遍历数组,for...in 通常是个坏主意。
  • 加载一个完整的库来遍历一个数组是毫无用处的:p
  • @Golmote:大多数 JavaScript 应用程序都可以从 jQuery 中受益。我想这不是这个项目中唯一存在的代码行。
【解决方案2】:

在大多数浏览器(不是 IE filter 方法,它并不能完全满足您的要求,但会为您创建一个原始数组中满足特定条件的元素数组:

function isGreaterThanFive(x) {
     return x > 5;
}

[1, 10, 4, 6].filter(isGreaterThanFive); // Returns [10, 6]

Mozilla Developer Network 有很多好的 JavaScript 资源。

【讨论】:

  • 只是想补充一下,它已从版本 9 开始添加到 IE。
  • 旁注:如果你想操作结果数组,你实际上是循环了两次。 (Alt:linq 延迟执行。)
【解决方案3】:

关于数组

您通常想要遍历数组的是forEach 方法:

arr.forEach(function(el) {
  alert(el);
});

在您增加数组的每个元素的特定情况下,我建议使用map 方法:

arr = arr.map(function(t){ return t+1; });

还有filterreduce等也派上用场。

但是就像 Tim Down 已经提到的那样,这些默认情况下在 IE 中不起作用。但是你也可以很容易地为 IE 添加这些方法,就像 MDC 文档中显示的那样,或者实际上你甚至可以编写比 MDC 文档中的更简单的版本(我不知道为什么它们在那里如此 un-JavaScript-y):

if (!Array.prototype.forEach) {
  Array.prototype.forEach = function(func, scope) {
    for (var i = 0, len = this.length; i < len; i++) {
      func.call(scope, this[i], i, this);
    }
  };
}

但不要将 for ... in 构造用于数组 - 这是用于对象的。

关于参考

另外,有时我想使用元素的值,有时我想将其用作参考。语法有什么区别?

在 JavaScript 中,每个变量实际上都是对某个对象的引用。但是这些引用是按值传递的。让我解释一下……

您可以将对象传递给修改对象的函数,并且更改将在函数外部看到:

function incrementHeight(person) {
  person.height = person.height + 1;
}
var p = {height: 10);
alert(p.height); // outputs: 10
incrementHeight(p);
alert(p.height); // outputs: 11

您可以在此处修改person 引用指向的值,因此更改将反映在函数之外。

但是这样的事情失败了:

function incrementHeight(height) {
  height = height + 1;
}
var h = 10;
alert(h); // outputs: 10
incrementHeight(h);
alert(h); // outputs: 10

在这里,您创建了一个全新的对象11,并将其引用分配给变量height。但是函数外的变量h 仍然包含旧的引用,因此仍然指向10

【讨论】:

    【解决方案4】:

    刚刚遇到同样的问题。 Tim Down 接近了,他只需要一个过滤数组长度的包装器:

    // count elements fulfilling a condition
    Array.prototype.count = function (f) {
      return this.filter(f).length;  
    };
    

    用法:

    // get the answer weight from the question's values array
    var w = Math.pow(q.values.count(function(v) { return v !== -1; }), -1);
    

    我希望这能回答这个长期存在的问题!

    【讨论】:

      【解决方案5】:

      这是编写过滤器的捷径。 它从一个数字数组中返回所有大于 5 的值。

      myArray.filter((x) => { return x > 5; })
      

      使用示例:

      var filterResult = [1, 10, 4, 6].filter((x) => { return x > 5; });
      console.log(filterResult); // returns [ 10, 6 ]
      

      这里还有一个对象数组的过滤器,它检查属性条件。

      myArray.filter((x) => { return x.myNumber > 5; })
      

      使用示例:

      var myArray = [{myNumber: 1, name: 'one'}, {myNumber: 3, name: 'tree'}, {myNumber: 6, name: 'six'}, {myNumber: 8, name: 'eight'}];
      var result = myArray.filter((x) => { return x.myNumber > 5; });
      console.log(result); // returns [ { myNumber: 6, name: 'six' }, { myNumber: 8, name: 'eight' } ]
      

      【讨论】:

        【解决方案6】:

        您可以使用Array.prototype.find,这正是您想要的,返回满足条件的第一个元素。 示例:

        > ([4, {a:7}, 7, {a:5, k:'r'}, 8]).find(o => o.a == 5)
        
        {a:5, k:'r'}
        

        【讨论】:

          【解决方案7】:

          编写一个接受各种条件的通用函数:

          function array_only(arr, condition) {
              hold_test=[]
              arr.map(function(e, i) {if(eval(condition)){hold_test.push(e)}})
              return(hold_test)
              }
          

          例子:

          use_array = ['hello', 'go_there', 'now', 'go_here', 'hello.png', 'gogo.log', 'hoho.png']
          

          用法

          返回只包含 .log 扩展名的元素:

          array_only(use_array, "e.includes('.log')")
          

          ['gogo.log']

          返回只包含 .png 扩展名的元素:

          array_only(use_array, "e.includes('.png')")
          

          [ 'hello.png', 'hoho.png' ]

          返回元素不包含 .png扩展:

          array_only(use_array, "!e.includes('.png')")
          

          ['你好','go_there','现在','go_here','gogo.log']

          return 元素包含 set 扩展和前缀:

          array_only(use_array, "['go_', '.png', '.log'].some(el => e.includes(el))")
          

          [ 'go_there', 'go_here', 'hello.png', 'gogo.log', 'hoho.png' ]

          您可以轻松通过多个条件

          返回所有长度小于 9 个字符的 png 文件:

          array_only(use_array, "e.includes('.png') && e.length<9")
          

          ['hoho.png']

          【讨论】:

            【解决方案8】:

            将 ES6 Array.filter()arrow functions 与表达式主体一起使用:

            myArray.filter(x => x > 5)
            

            比@Beauty 的回答简洁一点。

            【讨论】:

              【解决方案9】:

              问题:

              我需要知道是否存在任何 PJ 客户端的客户端集。

              解决方案:

              function deveExibirLista(lst: Clientes[]){
                  return lst.some(cli => cli.Documento === 14);
              }
              

              返回布尔值

              【讨论】:

                【解决方案10】:

                我加入晚了,但我有一个有趣的解决方案。如果你只想过滤单个元素,即第一个满足条件的元素,你可以使用 JS 的 find 函数。

                myArray.find(x => x > 5)
                

                【讨论】:

                  猜你喜欢
                  • 2022-01-08
                  • 2021-02-15
                  • 1970-01-01
                  • 2018-12-08
                  • 2019-05-13
                  • 2017-08-09
                  • 2018-07-26
                  • 1970-01-01
                  相关资源
                  最近更新 更多