何时/为何使用map/reduce over for循环

16 javascript

所以我第一次在JavaScript中进行了一些对象操作,我有一个问题,我想知道是否有人可以回答.

当我有一个我想要操作的对象时,我可以做一些嵌套for循环的程度,但是有一些内置于JavaScript中的函数,比如map/reduce/filter,以及像lodash/underscore这样的库.

我认为后者(map/reduce/filter和库)是更好的练习,但我只是好奇为什么.

我正在做一些非常基本的对象操作,可以通过一些很好的放置for循环来抓取和更改对象中的正确键/值,但可以使用JS中的函数/库轻松完成.只是好奇它们如何更好 - 比如更好的性能/更清洁的代码/易用性/其他任何东西.

道歉,没有代码.我非常感谢任何帮助我在这里了解更多的人.

编辑 - 所以从示例中获取map()

我可以以javascript.map为例

 var kvArray = [{key:1, value:10}, {key:2, value:20}, {key:3, value: 30}];
var reformattedArray = kvArray.map(function(obj){ 
var rObj = {};
rObj[obj.key] = obj.value;
return rObj;
});
Run Code Online (Sandbox Code Playgroud)

我可以做点什么

   var kvArray = [{key:1, value:10}, {key:2, value:20}, {key:3, value: 30}];
var reformattedArray = [];

for(var object in kvArray){
  //combine both values into object inside of kvArray[object]);
 };
Run Code Online (Sandbox Code Playgroud)

代码少得多 - 但还有其他值得了解的好处吗?

Nar*_*mar 14

我知道我回复了一个旧答案,但只想指出未来的读者.

Map reduce和filter函数来自函数式编程领域.

这些是使用lisp,haskell和其他语言(ml?)等语言构建的第一类运算符.函数式语言倾向于在不可变数据上运行运算符,而不是让代码在数据上运行以对其进行操作(比如循环).因此,与提供for和while循环相比,它们提供了更简单但功能更强大的接口,如map,filter和reduce.

它还可以帮助他们满足其他要求,例如不变性等.这就是为什么地图会给你一个新地图而不是改变旧地图.从并发的角度来看,这些都非常好,尽管它们在某些情况下可能会更慢.

这种方法通常可以减少多线程或高并发应用程序中的代码错误.当多个参与者对同一条数据进行操作时,不变性有助于防止代码踩到彼此的脚趾.

由于javascript试图通过提供函数式编程语言的一些功能来尝试部分功能,因此在它中实现map,filter和reduce功能可能也是有意义的.

YMMV取决于您使用的工具所做的事情.

如果你的代码在for循环中效果更好,那就去吧.

但是如果你发现异步代码咀嚼公共数据并且最终分裂你的头发试图调试循环.打个招呼,映射,缩小和过滤.

我的2卢比

  • 我滥用了这个...... [艺术许可证](https://en.wikipedia.org/wiki/Artistic_license).如果你那么迂腐,请忽略. (4认同)

jfr*_*d00 8

.map()允许您通过迭代原始数组并允许您运行某种自定义转换函数来创建新数组.输出来自.map()一个新数组.

var orig = [1,2,3,4,5];
var squares = orig.map(function(val) {
    return val * val;
});
console.log(squares);   // [1,4,9,16,25]
Run Code Online (Sandbox Code Playgroud)

.reduce() 允许您迭代累积单个结果或对象的数组.

var orig = [1,2,3,4,5];
var sum = orig.reduce(function(cum, val) {
    return cum + val;
}, 0);
console.log(sum);    // 15
Run Code Online (Sandbox Code Playgroud)

这些是专门的迭代器.当这种类型的输出完全符合您的要求时,您可以使用它们.它们不像for循环那样灵活(例如,你不能像for循环中那样停止迭代),但是对于特定类型的操作而言,它们的输入较少,对于了解它们的人来说,它们很可能是更容易看到代码的意图.

我还没有自己测试的性能.map(),并.reduce()与一for环,但已经看到了试验.forEach(),其结果表明.forEach()在某些浏览器实际上慢.这可能是因为循环的每次迭代.forEach()都必须调用你的回调函数,而在普通for循环中,你不必进行这样的函数调用(代码可以直接嵌入那里).在任何情况下,这种类型的性能差异实际上很有意义,并且通常应该使用哪种构造使代码更清晰,更容易维护.

如果你真的想要优化性能,你必须在像jsperf这样的工具中编写自己的测试用例,然后在多个浏览器中运行它,看看哪种做法最适合你的特定情况.


for循环的另一个优点是它可以用于类似数组的对象,例如HTMLCollection,它们不是实际的数组,因此没有类似.reduce()和的方法.map().

  • 从我的角度来看,关于`for` vs` .map()`/`.forEach()`以及其他的性能的理想答案是:它们是相同的,它们的复杂性是线性的(与集合中元素的数量成正比) ). (2认同)

Llo*_*nks 7

这就像问我是否更喜欢篮球或足球.两者都有积极的一面.

如果你有10个开发人员看你的for循环,那么10个中的9个会立即知道你在做什么.也许有一半人不得不查看map()方法是什么,但他们也会知道发生了什么.所以在这方面,for循环更容易让其他人阅读.

另一方面,map()将为您节省两到三行代码.

就性能而言,你会发现map()内部构建的东西类似于for循环.如果通过大型迭代运行它们,在性能速度方面可能会看到几毫秒的差异; 但它们永远不会被最终用户识别.

  • "所以在这方面,for循环更容易让其他人阅读." ---如果你不教你的后辈 - 你将永远使用古老的技术,因为"否则对他们来说很难" (10认同)
  • 我几乎不认为for循环应该被视为一种"古老技术",特别是因为它通常比专用迭代器快许多倍.而map和reduce已经存在了很长时间,它们只是javascript中的新功能.所以年龄与它无关.考虑自己教:-) (5认同)
  • “在性能速度方面,您可能会看到几毫秒的差异”。几毫秒乘以几千或几百万个项目加起来相当快。在我自己的测试中(当决定使用 .map 与 for 时),我发现使用 map 迭代大量数据将花费近一个数量级的时间。为了保持一致性,我在其他地方都编写了 for 循环。这也是有利的,因为来自其他语言的开发人员可以直接跳入并了解发生了什么。 (2认同)

Jua*_*dez 5

forEach():为每个数组元素执行一次提供的函数(回调)。不返回任何内容(undefined),但允许此回调改变调用数组。

map():为每个数组元素执行一次提供的函数(回调),并使用此执行的结果创建一个新数组。它不能改变调用数组的内容。

结论 使用map(),当你需要返回一个新的数组,使用forEach()for当你想改变原来的数组。