【问题标题】:functional way to iterate over range (ES6/7) [duplicate]迭代范围的功能方法(ES6/7)[重复]
【发布时间】:2015-08-19 11:38:29
【问题描述】:

以更实用的方式执行以下操作的最佳方法是什么(使用 ES6/ES7)

let cols = [];
for (let i =0; i <= 7; i++) {
   cols.push(i * i);
}
return cols;

我试过了,

return [ ...7 ].map(i => {
  return i * i;
});

但是翻译成

[].concat(7).map(function (n) {
  return n * n;
});

这不是我所期望的。

编辑:

@pavlo。的确,这是一个错误。我使用的是 JSX,例如,我想要 7 个 div,(未经测试)

let cols = [];
    for (let i =0; i <= 7; i++) {
       cols.push(<div id={i}> ...  </div>)
    }
    return cols;

所以这个想法确实是为了减少临时变量的数量和程序感觉。

【问题讨论】:

  • 您想对每个数字 1-7 进行平方吗?
  • 在第一个示例中,您可能指的是cols.push(i * i),而不是return i * i

标签: javascript functional-programming ecmascript-6 ecmascript-harmony


【解决方案1】:

可以创建一个空数组,填充它(否则 map 会跳过它),然后将索引映射到值:

Array(8).fill(0).map((_, i) => i * i);

【讨论】:

  • 如果不需要 map 中的结果数组,并且您想在其中保留 'for' 字,可以使用 Array(8).fill().forEach((_,i)=&gt;console.log(i))[...Array(8)].forEach((_,i)=&gt;console.log(i))
  • 请注意,此代码将在 Typescript 中失败,除非您将 undefined 作为第一个参数添加到 fill。根据this github issue,Typescript 维护人员似乎反对这种对Array.prototype.fill 的特定使用。
  • 谢谢,亚当。出于实际目的,我已将答案更新为使用.fill(0)
  • 就我而言,这个答案对我有很大帮助,谢谢。
  • Array.from({length: 8}, (_, i) =&gt; i * i)
【解决方案2】:

这是一种使用生成器的方法:

function* square(n) {
    for (var i = 0; i < n; i++ ) yield i*i;
}

那你就可以写了

console.log(...square(7));

另一个想法是:

[...Array(5)].map((_, i) => i*i)

Array(5) 创建一个未填充的五元素数组。这就是Array 在给定单个参数时的工作方式。我们使用扩展运算符创建一个包含五个未定义元素的数组。然后我们可以映射。见http://ariya.ofilabs.com/2013/07/sequences-using-javascript-array.html

或者,我们可以写

Array.from(Array(5)).map((_, i) => i*i)

或者,我们可以利用Array#from 的第二个参数跳过map 并写入

Array.from(Array(5), (_, i) => i*i)

我最近看到的一个可怕的 hack,我确实推荐你使用,是

[...1e4+''].map((_, i) => i*i)

【讨论】:

  • Array(...Array(5)) 更好地表达为[...Array(5)]
【解决方案3】:

ES7 提案

警告:不幸的是,我相信大多数流行平台已经放弃了对推导式的支持。请参阅下文了解支持良好的 ES6 方法

你总是可以使用类似的东西:

[for (i of Array(7).keys()) i*i];

在 Firefox 上运行此代码:

[0,1,4,9,16,25,36]

这适用于 Firefox(这是一个提议的 ES7 功能),但它已从规范中删除。 IIRC,启用“实验”的 Babel 5 支持这一点。

这是您最好的选择,因为数组理解仅用于此目的。你甚至可以编写一个范围函数来配合这个:

var range = (u, l = 0) => [ for( i of Array(u - l).keys() ) i + l ]

那么你可以这样做:

[for (i of range(5)) i*i] // 0, 1, 4, 9, 16, 25
[for (i of range(5,3)) i*i] // 9, 16, 25

ES6

一个很好的方法来做到这一点:

[...Array(7).keys()].map(i => i * i);
Array(7).fill().map((_,i) => i*i);
[...Array(7)].map((_,i) => i*i);

这将输出:

[0,1,4,9,16,25,36]

【讨论】:

  • @vihan1086: ES 多次提出数组解析,但没有在规范中提出。 .map(i =&gt; i*i) 被认为要简单得多:-)
  • 当我尝试它时这不起作用: Array(7).keys().map(i => i * i); keys() 返回了一个迭代器。但是这可行: Array.from(Array(7).keys()).map(i => i * i) 注意到需要将迭代器显式加载到另一个数组中。
  • @arcseldon 不,它不起作用。我不确定我在发帖时在想什么:p 会修复
  • 数组理解不是 ES7 的一部分。据我所知,这甚至不再是一个提案了。
  • 至少不要声称它们在 ES7 中。那只会让人们感到困惑。我认为 Babel 不再支持它们了:babeljs.io/docs/plugins .
猜你喜欢
  • 2016-07-11
  • 1970-01-01
  • 1970-01-01
  • 2012-11-27
  • 1970-01-01
  • 1970-01-01
  • 2017-05-02
  • 2016-10-08
相关资源
最近更新 更多