什么是“for(var i = 0; i< size; i ++)”循环的可能功能替代?

时间:2014-02-24 08:01:00

标签: javascript functional-programming

我想要普通的解决方案。我写的很多 for (var i = 0; i < someSize; i++) {...}

请注意,它不是用于迭代数组或 DOM 节点,而是主要用于纯计算。

我想要更多功能性方法因为我 lazy 。就像是: new Array(15).forEach(function(i, idx) { ... ... })

但这不起作用。

使用我曾经写过的underscore _.range(0,100,4).forEach(function(i, idx) { doSomethingWith(i); });

请注意,它可能不实用,但我喜欢弯曲Javascript。

2 个答案:

答案 0 :(得分:2)

不确定你真正想要的是什么,但你可以拥有一个通用的迭代器函数来管理你的循环计数器:

function loop(start, stop, fn) {
   for (var i = start; i < stop; i++) {
       if (fn(i) === false) {
           return;
       }
   }
}

然后,您可以像这样使用它:

loop(0, size, function(i) {
    // use i here
});

您甚至可以将起始值设为可选(如果不存在则默认为零):

function loop(start, stop, fn) {
   if (!fn) {
      fn = stop;
      stop = start;
      start = 0;
   }
   for (var i = start; i < stop; i++) {
       if (fn(i) === false) {
           return;
       }
   }
}

loop(size, function(i) {
    // use i here
});

答案 1 :(得分:2)

这不起作用的原因似乎是因为forEach没有迭代使用类似数组构造函数时设置的undefined值。

forEach适用于实际拥有内容的数组,正如您在运行这样的代码时所看到的那样:

[1,2,3,4,5,6,7,8].forEach(function(){console.log(arguments)});

所以,现在,你要找的就是用内容正确初始化一个新数组。

在这方面,{p> This question on SO有一些有用的答案 最短的解决方案似乎是:

new Array(5+1).join('0').split('')

您可以在此之后简单地链接forEach

或者,您可以从该问题中一个更受欢迎的答案中提取原型:

Array.prototype.init = function(value, length){
    return Array.apply(null, new Array(length)).map(function(){
        return value.valueOf();
    },value);
}

这允许你做这样的事情:

[].init('foo', 3);
// ["foo", "foo", "foo"]
[].init(60, 4);
// [60, 60, 60, 60]
[].init({}, 3);
// [{},{},{}]
[].init(true, 9);
// [true, true, true, true, true, true, true, true, true]

您当然可以在.forEach()之后链接init()

(实际上,如果你不将此函数添加到Array.prototype,你可以使用init(),而不使用数组文字。这可能是一个“更清洁”的解决方案)