如何在javascript中迭代数组

时间:2012-05-22 15:53:56

标签: javascript arrays loops

我有一个像var arr = { 30,80,20,100 };

这样的数组

现在我想迭代上面的数组并将迭代的单个值添加到一个函数return语句中,例如

function iterate()
{
    return "Hours" + arr[i];
}

我曾尝试过以下方法

function m()
{
    for(var i in arr)
    {
        s = arr[i];
    }
    document.write(s);
}

上面的代码只给出一个值,即数组中的最后一个值。但我想迭代所有值,如

30---for first Iteration
80---for second Iteraton

Any help will be appreciated

3 个答案:

答案 0 :(得分:24)

如上所述,有几种方法可以遍历数组。

for .. in

for(var i in arr) {
    console.log("Property: " + i);
    console.log("Value: " + arr[i]);
}

这是数组迭代技术。它是一种对象属性迭代技术。它只是因为Arrays也是对象,这个几乎可以工作,但你最终得到的不是数组元素,比如length属性和你可能拥有的任何属性添加到对象。

for( ; ; )

for(var i = 0; i < arr.length; i++) {
    console.log("Index: " + i);
    console.log("Value: " + arr[i]);
}

这是循环遍历数组的经典 C风格for循环(稍微适应Javascript,因为数组可以告诉你它的长度,而你需要跟踪它你自己在C)。这可能就是你想要的。

.forEach(callback, this)

arr.forEach(function(val, ind, ar2) {
    console.log("Index: " + ind);
    console.log("Value: " + val);
    console.log("Array: " + ar2);
    console.log("this: " + this);
}, optionalThisObject);

这是一个通过数组的函数式循环。您调用数组的forEach方法并将其传递给具有1-3个参数的函数。第一个参数是数组的已解析值,第二个参数是找到它的索引,第三个参数是对整个数组的引用。你通常只需要第一个参数,有时是第二个,很少是第三个。

您还可以将第二个参数传递给forEach,作为您的函数应该将其视为this的对象。这种功能的用法更加深奥,但基本上,如果不是匿名函数,则将其编写为命名函数,对数组执行某些操作并将结果写入其中&#34; s&#34; parent&#34;对象,然后你可以选择&#34;父母&#34;对象在运行时通过指定调用forEach时的内容。

map, reduce, filter, every, some, reduceRight

常见的迭代模式在函数式编程中有自己的名称,这使得代码更短,但需要更多先验知识才能看到正在发生的事情。它们仍然是非常有用的结构,可以被链接以将数十行压缩成少数几行。

var newArr = arr.map(function(val, ind, ar2) {
    return val*ind;
}, optionalThisArg);

map看起来与forEach非常相似,但它通过数组获取每次迭代的返回值,并使用它来组装新数组。这使您可以使用非常少的代码行来转换数据(而未来的ECMAScript 6的匿名函数速记应该只需要一行代码。)

var newVal = arr.reduce(function(prev, curr, ind, ar2) {
    return prev+curr;
}, initial);

reduce从左到右遍历数组(0到length-1)并获取将值合并在一起的函数。 prev是前一次迭代通过函数返回的值(或initial值),curr是数组当前ind ex的值,{ {1}}和ind现在应该有意义了。这会将整个数组减少为单个值,从而可以生成总数,平均值或其他值。 (例如,它也可以在ar2内用于将二维数组数组缩减为单个数组。)

map只是reduceRight,但是从右到左(长度为1到0)。

reduce

var newArr = arr.filter(function(val, ind, ar2) { return val > ind; }, optionalThisArg); 看起来像filtermap,并生成一个新的数组,如forEach,但新数组的长度可能赢了& #39; t与旧数组的长度相同。 map假定传递的函数返回一个布尔值。如果布尔值为filter,则将值放入新数组中,如果它被跳过true。顾名思义,false过滤掉您不希望在数组中使用的数据。

filter

var newBool = arr.every(function(val, ind, ar2) { return val > ind; }, optionalThisArg); var newBool2 = arr.some(function(val, ind, ar2) { return val > ind; }, optionalThisArg); every看起来与some非常相似,但它们会返回布尔值,而不是过滤后的数组。对于filter,如果每个元素都通过测试,则返回every,否则返回true,而false如果任何元素通过测试则返回true,否则返回some 。你不会经常看到这些,但是如果某个元素通过了测试,那么它们在查询整个数组的情况下是有意义的,或者如果任何元素未通过测试你就不想要数组。 (例如,它可以在数组数组的false内使用。)

即将推出的ES6标准:filter

for .. of类似,for .. in遍历对象属性的集合,而不是数组索引,但您可能会觉得这很有用。

for .. of

for(var i of Obj) { console.log("Value: " + i); } 跳过属性名称并立即转到属性值,因此您不必在代码中到处都有丑陋的for .. of。没有浏览器(我很清楚)实现了这一点。

ECMA不接受Firefox扩展,但仅在Firefox上可用:Obj[i]

for each .. in

这是Mozilla最初为for each(var i in Obj) { console.log("Value: " + i); } 提出的语法,您现在可以在Firefox中使用它,但我确实不建议您这样做。

不是数组迭代,但相关:for .. of

如果您发现Array对象的函数式迭代很好,但希望您可以将它应用于Objects,那么这就是您的方法。

Object.keys()

此方法生成一个字符串数组,其中每个字符串都是源对象的键。

功能样式示例

因此,我们想要获得对象上所有数值的绝对值的平均值。 (为什么?我不知道。这只是强调这些酷炫功能的一个很好的例子。)首先,让我们以强制性的方式做到这一点:

var newArr = Object.keys(Obj);

这不是太糟糕,但现在我们的范围中有两个变量,var average = 0, j = 0; for(var i in Obj) { if(!isNaN(Obj[i]) { j++; average += Math.abs(Obj[i]); } } average /= j; average。我们可能希望j在那里,但在此计算之后,我们无法关心average。让我们来看一个功能版本:

j

在这种情况下,我们得到一个键数组,并使用非数字值过滤掉键,然后我们将剩余键的数组映射到一个数字数组,这些数字都是正数,然后我们计算平均值减少(使用滚动平均方程),我们告诉它以平均零开始。

如果我们用ECMAScript 6&{39}重写上述功能代码(尚未由浏览器实现),我们会更短:

var average = Object.keys(Obj).filter(function(val) {
    return !isNaN(Obj[val]);
}).map(function(val) {
    return Math.abs(Obj[val]);
}).reduce(function(prev, curr, ind) {
    return (prev*ind + curr) / (ind + 1);
}, 0);

这看起来很棒,对吧?

结论

如果你坚持命令式:

var average = Object.keys(Obj)
    .filter(val => !isNaN(Obj[val]))
    .map(val => Math.abs(Obj[val]))
    .reduce((prev, curr, ind) => (prev*ind + curr) / (ind + 1), 0);

如果你选择功能风格:

for(var i = 0; i < arr.length; i++) {
    console.log("Hours: " + arr[i]);
}

功能风格将让你编写真正强大的代码,特别是当新的&#34;胖箭头&#34;添加了匿名函数语法。

答案 1 :(得分:2)

迭代使用length属性而不是for ... in语句,并从循环内部写入数组值。

for (var ii = 0, len = arr.length; ii < len; ii++) {
  document.write(arr[ii]);
}

答案 2 :(得分:1)

那是因为你的write语句在循环之外。你不想这样吗?

function m(arr) {
    for (var i = 0; i < arr.length; i++) {
        s = arr[i];
        document.write(s);
    }

}​

另外,不要使用in,因为它会为你提供数组的所有属性。使用array.length