JavaScript - 获取满足条件的数组元素

73
我正在使用W3C学习JavaScript,但是没有找到这个问题的答案。
我试图对满足某些条件的数组元素进行一些操作。
除了在for循环中运行数组元素以外,是否有其他方法可以实现呢? 也许像其他语言一样做些什么:
foreach (object t in tArray)
   if (t follows some condition...) t++;

另外一件事,有时我想使用元素的值,有时我想将其作为引用。这两种情况的语法区别是什么?

此外,如果你能推荐更全面的学习JavaScript的网站,我会很高兴的。


学习Javascript,可以尝试访问Mozilla开发者中心Web标准课程 - Yi Jiang
10个回答

70

大多数浏览器(不包括IE <= 8)都有一个filter方法,它不完全符合您的需求,但会创建一个由原始数组中满足特定条件的元素组成的新数组:

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

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

Mozilla 开发者网络 拥有许多优质的 JavaScript 资源。


1
只是想补充一下,它从IE 9版本开始就已经被添加了。 - Miika L.
旁注:如果您想操作结果数组,则实际上需要循环两次。(另一种选择是使用延迟执行的linq。) - Joel Harkes

36

12

这是一种简短的方式编写过滤器。 从数字数组中返回所有大于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' } ]

9
您可以使用 Array.prototype.find,它能精确地实现您所需的功能:返回第一个满足条件的元素。 示例:
> ([4, {a:7}, 7, {a:5, k:'r'}, 8]).find(o => o.a == 5)

{a:5, k:'r'}

4
您可以在JavaScript中使用for ... in:
for (var key in array) {
    if (/* some condition */) {
        // ...
    }
}

从 JavaScript 1.6 版本开始,您也可以使用此功能:
for each (var element in array) {
    // ...
}

这些主要用于遍历对象属性。您应该考虑简单地使用for循环。

编辑:您可以使用JavaScript框架,如jQuery来消除这些跨浏览器的问题。试试看。它的$.each()方法可以完成任务。


是的,这些方法是可行的,但通常不建议使用。原因是它还会枚举数组对象的其他属性(许多库都添加了这些属性),这将产生不可预测的结果。 - sje397
@sje397:没错。我强烈推荐使用jQuery来完成这个任务。它的$.each()方法非常好用,而且提供了闭包。由于JavaScript具有函数作用域,在循环中执行大量操作时,这非常有帮助。 - jwueller
1
for...in 枚举的属性集是可以预测的,尽管在不同的浏览器中可能会有所不同。然而,迭代顺序通常是不可预测的。对于数组的迭代,使用 for...in 通常是不好的选择。 - Tim Down
加载整个库来迭代数组是相当无用的:p - Golmote Kinoko
@Golmote:大多数JavaScript应用程序都可以从jQuery中受益。我想这不是该项目中唯一存在的代码行。 - jwueller
请使用 for...of - bb216b3acfd8f72cbc8f899d4d6963

2

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

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', 'hoho' ]

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

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

[ '你好', '去那里', '现在', '来这里', 'gogo.log' ]

返回包含扩展和前缀的集合元素:

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' ]


2

虽然我来晚了,但是我有一个有趣的解决方案。如果你只想过滤单个元素,即第一个符合条件的元素,你可以使用JS的find函数。

myArray.find(x => x > 5)

2

关于数组

通常用于迭代数组的方法是forEach方法:

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

在您需要对数组中的每个元素进行递增操作时,我建议使用 map 方法:
arr = arr.map(function(t){ return t+1; });

还有其他一些在it技术中很有用的方法,比如filterreduce

但是正如Tim Down所提到的那样,这些方法默认情况下无法在IE中使用。但你可以像MDC文档中所示那样轻松地为IE添加这些方法,或者实际上你甚至可以编写比MDC文档中更简单的版本(我不知道它们为什么如此不符合JavaScript风格):

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


0

刚刚遇到了同样的问题。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);

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


0
问题:
我需要知道是否存在任何PJ客户端的客户端集。
解决方案:
function deveExibirLista(lst: Clientes[]){
    return lst.some(cli => cli.Documento === 14);
}

它返回布尔值


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接