当前位置:  开发笔记 > 编程语言 > 正文

foreach和地图之间有区别吗?

如何解决《foreach和地图之间有区别吗?》经验,为你挑选了6个好方法。

好吧,这更像是一个计算机科学问题,而不是一个基于特定语言的问题,但是地图操作和foreach操作之间有区别吗?或者它们只是同一个东西的不同名称?



1> madlep..:

不同.

foreach迭代列表并将一些带副作用的操作应用于每个列表成员(例如将每个操作保存到数据库中)

map迭代列表,转换该列表的每个成员,并返回另一个与转换成员相同大小的列表(例如将字符串列表转换为大写)


但你也可能在地图功能中发生副作用.我喜欢这个答案:http://stackoverflow.com/a/4927981/375688
一个重要的要点(在Scala中尤其如此)是对`map`的调用不会**导致执行其底层逻辑,直到召唤预期的变换列表为止.相反,`foreach`的操作立即计算.

2> Henk..:

它们之间的重要区别在于将map所有结果累积到集合中,而不foreach返回任何结果.map当你想用函数转换元素集合时,通常使用它,而foreach只是为每个元素执行一个动作.



3> wilhelmtell..:

简而言之,foreach用于对元素集合的每个元素应用操作,而map用于将一个集合转换为另一个集合.

foreach和之间有两个显着的差异map.

    foreach对它所应用的操作没有概念上的限制,除了可能接受一个元素作为参数.也就是说,操作可能无效,可能具有副作用,可能返回值或可能不返回值.所有foreach关心的是迭代元素集合,并对每个元素应用操作.

    map另一方面,对操作有一个限制:它期望操作返回一个元素,并且可能还接受一个元素作为参数.该map操作迭代元素集合,对每个元素应用操作,最后将每次调用操作的结果存储到另一个集合中.换句话说,map 一个集合转换为另一个集合.

    foreach适用于单个元素集合.这是输入集合.

    map 使用两个元素集合:输入集合和输出集合.

将两种算法联系起来并不是一个错误:实际上,您可以分层次地查看这两种算法,其中map是两种算法的特化foreach.也就是说,您可以使用foreach并让操作转换其参数并将其插入另一个集合中.因此,该foreach算法是算法的抽象,概括map.实际上,因为foreach对它的操作没有限制,我们可以有把握地说这foreach是最简单的循环机制,它可以做循环可以做的任何事情.map,以及其他更专业的算法,是表达性:如果你想将一个集合映射(或转换)到另一个集合,如果你使用的map话,你的意图比你使用时更清晰foreach.

我们可以进一步扩展这个讨论,并考虑copy算法:克隆集合的循环.该算法也是该算法的专业化foreach.您可以定义一个操作,给定一个元素,将该元素插入另一个集合中.如果您使用foreach该操作,您实际上执行了copy算法,尽管清晰度,表现力或表现力都降低了.让我们更进一步:我们可以说这map是一个专业化copy,本身就是一个专业化foreach.map可以改变它迭代的任何元素.如果map不更改任何元素,那么它只是复制元素,并使用副本 会更清楚地表达意图.

foreach算法本身可能会或可能不会有一个返回值,根据语言.例如,在C++中,foreach返回它最初接收的操作.这个想法是操作可能有一个状态,你可能希望该操作回来检查它是如何在元素上进化的.map也可能会或可能不会返回值.在C++中transform(map这里的等价物)碰巧将迭代器返回到输出容器(集合)的末尾.在Ruby中,返回值map是输出序列(集合).因此,算法的返回值实际上是一个实现细节; 他们的影响可能是也可能不是他们的回报.



4> abhisekp..:

Array.protototype.map方法&Array.protototype.forEach都非常相似.

运行以下代码:http://labs.codecademy.com/bw1/6#:workspace

var arr = [1, 2, 3, 4, 5];

arr.map(function(val, ind, arr){
    console.log("arr[" + ind + "]: " + Math.pow(val,2));
});

console.log();

arr.forEach(function(val, ind, arr){
    console.log("arr[" + ind + "]: " + Math.pow(val,2));
});

他们给出了完全相同的结果.

arr[0]: 1
arr[1]: 4
arr[2]: 9
arr[3]: 16
arr[4]: 25

arr[0]: 1
arr[1]: 4
arr[2]: 9
arr[3]: 16
arr[4]: 25

但是,当您运行以下代码时,就会出现这种情况: -

在这里,我只是简单地从map和forEach方法中分配了返回值的结果.

var arr = [1, 2, 3, 4, 5];

var ar1 = arr.map(function(val, ind, arr){
    console.log("arr[" + ind + "]: " + Math.pow(val,2));
    return val;
});

console.log();
console.log(ar1);
console.log();

var ar2 = arr.forEach(function(val, ind, arr){
    console.log("arr[" + ind + "]: " + Math.pow(val,2));
    return val;
});

console.log();
console.log(ar2);
console.log();

现在结果很棘手!

arr[0]: 1
arr[1]: 4
arr[2]: 9
arr[3]: 16
arr[4]: 25

[ 1, 2, 3, 4, 5 ]

arr[0]: 1
arr[1]: 4
arr[2]: 9
arr[3]: 16
arr[4]: 25

undefined
结论

Array.prototype.map返回一个数组,但Array.prototype.forEach没有.因此,您可以在传递给map方法的回调函数内操作返回的数组,然后返回它.

Array.prototype.forEach 只遍历给定的数组,这样你就可以在走数组时做你的东西了.



5> Javier..:

最"可见"的区别是,map会将结果累积到新集合中,而foreach仅针对执行本身进行.

但还有一些额外的假设:由于地图的"目的"是新的价值清单,因此执行的顺序并不重要.事实上,一些执行环境生成并行代码,甚至引入一些memoizing以避免调用重复值或者懒惰,以避免调用某些代码.

另一方面,foreach被称为副作用; 因此,顺序很重要,通常不能并行化.



6> Sumukh Barve..:

简短的回答: map并且forEach是不同的.另外,非正式地说,map是一个严格的超集forEach.

龙回答:首先,让我们拿出一个行描述forEachmap:

forEach 迭代所有元素,在每个元素上调用提供的函数.

map 迭代所有元素,在每个元素上调用提供的函数,并通过记住每个函数调用的结果来生成转换后的数组.

在许多语言中,forEach通常被称为公正each.以下讨论仅使用JavaScript作为参考.它可能真的是任何其他语言.

现在,让我们使用这些功能.

使用forEach:

任务1:编写一个printSquares接受数字数组的函数arr,并打印其中每个元素的平方.

解决方案1:

var printSquares = function (arr) {
    arr.forEach(function (n) {
        console.log(n * n);
    });
};

使用map:

任务2:编写一个selfDot接受数字数组的函数arr,并返回一个数组,其中每个元素都是相应元素的平方arr.

旁白:在这里,在俚语中,我们试图对输入数组进行平方.正式地说,我们正试图用自己来计算它的点积.

解决方案2:

var selfDot = function (arr) {
    return arr.map(function (n) {
        return n * n;
    });
};

如何是map的超集forEach

您可以使用任务1任务2map来解决这两个任务.但是,您无法使用解决任务2.forEach

解决方案1中,如果您只是替换forEachmap,则解决方案仍然有效.但是,在解决方案2中,替换mapforEach将破坏以前工作的解决方案.

实施forEach方面map:

实现的另一种方式map的优势是落实forEach在以下方面map.由于我们是优秀的程序员,我们不会沉迷于命名空间污染.我们会打电话给我们的forEach,只是each.

Array.prototype.each = function (func) {
    this.map(func);
};

现在,如果你不喜欢这些prototype废话,你可以去:

var each = function (arr, func) {
    arr.map(func); // Or map(arr, func);
};

所以,嗯..为什么forEach甚至存在?

答案是效率.如果您对将数组转换为另一个数组不感兴趣,为什么要计算转换后的数组呢?只是为了转储它?当然不是!如果您不想进行转换,则不应进行转换.

因此,虽然map可用于解决任务1,但它可能不应该.因为每个人都是合适的人选.


原始答案:

虽然我主要与@madlep的答案达成一致,我想指出的是,map()是一个严格的超集forEach().

是的,map()通常用于创建新数组.但是,它可用于更改当前阵列.

这是一个例子:

var a = [0, 1, 2, 3, 4], b = null;
b = a.map(function (x) { a[x] = 'What!!'; return x*x; });
console.log(b); // logs [0, 1, 4, 9, 16] 
console.log(a); // logs ["What!!", "What!!", "What!!", "What!!", "What!!"]

在上面的例子中,a方便地设置a[i] === ii < a.length.即便如此,它也证明了它的力量map().

这是官方的描述map().请注意,map()甚至可能会更改调用它的数组!冰雹map().

希望这有帮助.


2015年11月10日编辑:增加了详细说明.

推荐阅读
kikokikolove
这个屌丝很懒,什么也没留下!
DevBox开发工具箱 | 专业的在线开发工具网站    京公网安备 11010802040832号  |  京ICP备19059560号-6
Copyright © 1998 - 2020 DevBox.CN. All Rights Reserved devBox.cn 开发工具箱 版权所有