代码改变世界

遍历用for还是foreach?

2024-02-18 14:11  萤火架构  阅读(2531)  评论(4编辑  收藏  举报

遍历用for还是foreach?这篇文章帮你轻松选择!

在编程的世界里,我们经常需要对数据进行循环处理,常用的两种方法就是:for循环和foreach循环。想象你站在一条装满宝贝的传送带前,你要亲手检查每一件宝贝。使用for循环就像是你亲手控制传送带的速度和方向,而使用foreach循环则是传送带自动运转,你只需专注于宝贝本身。好,下面就让我们一步步深入了解下这两种方法吧!

应用场景

for循环:好比你手握一张购物清单(索引),按照顺序逐项挑选商品。在数组、列表等数据结构中,for循环通过下标访问元素。这意味着,当你需要特定的遍历顺序,或者想要在循环中更改计数器时,for循环就是你的菜。

foreach循环:更像是一个自动售货机,你只需站在出口等待,它会按顺序一个个送出商品。foreach适用于不需要关心索引,仅需遍历并处理每个元素的情况。尤其在处理集合类时,foreach更显简洁高效。

使用方法

我们用一个例子来感受一下for和foreach吧。假设你是个游戏玩家,你有一排宝箱需要打开。

for循环的使用:在for循环中,通常会定义一个迭代变量,并指定迭代变量的初始值、循环条件和迭代变量的更新方式,在循环体中根据索引值访问数组或列表中的元素。

let treasureChests = ['金币', '宝石', '魔法药水', '地图', '钥匙'];
// 使用for循环打开每个宝箱
for (let i = 0; i < treasureChests.length; i++) {
    openChest(treasureChests[i]); // 打开宝箱
}

在这段JavaScript代码里,i就像是你手里的遥控器,从0开始按,一直按到最后一个宝箱。

foreach循环的使用:foreach简化了迭代过程,不需要显式地定义迭代变量和更新迭代变量,也就是无需手动管理索引,编译器会自动帮我们完成元素的迭代获取。

treasureChests.forEach((chest) => {
    openChest(chest); // 打开宝箱
});

这里的foreach循环直接告诉你“这是个宝箱”,然后你就打开它。注意,我们这里没有使用索引,它是自动遍历数组中的每个元素。

注意在大多数现代编程语言中,foreach 循环(或其等效的遍历结构)设计的初衷是用来读取集合中的元素,而不是用于修改集合本身,因此我们无法在 foreach 循环中直接更改集合中对象的引用,但是我们可以修改对象中的属性。

C#的例子:

foreach (var item in collection)
{
    item.Property = newValue; // 允许修改对象的属性
    // item = new Object(); // 错误!不允许修改对象的引用
}

还需要注意如果集合中的元素是值类型或者基本数据类型,如int、double、string等,当你在foreach循环中迭代时,由于每次迭代获取的是该元素的一个副本,因此直接修改这个副本不会影响原数组中的元素。

let numbers = [1, 2, 3];

numbers.forEach(item => {
  item = 4; // 这不会改变原始数组
});

console.log(numbers); // [1, 2, 3]

底层原理

for循环像是有条不紊的工厂流水线。在每次迭代中,都有一个明确的开始(初始化表达式),一个持续条件(条件表达式),和一个精确的进度控制(迭代表达式)。这个流水线会在你设定的条件下反复运转,直到任务完成。

foreach循环则更像是智能的机器人,它内置了遍历的逻辑。在像Java、C#这样的语言中,foreach循环背后是基于Iterable接口的。只要集合实现了Iterable接口,就可以用foreach来遍历。机器人(foreach循环)会自动调用集合的iterator方法,获取一个迭代器,然后通过这个迭代器遍历集合中的每个元素。

编程思想

for循环体现的是一种经典的命令式编程思想,它关注如何通过明确的步骤去解决问题。你需要告诉程序每一个要执行的动作,这种方式给予了程序员高度的控制权,但同时也增加了复杂性和出错的可能性。

foreach循环则是声明式编程的体现,更关注做什么而不是怎么做。你只需要声明你的需求(遍历集合),具体的遍历逻辑则被抽象掉了。这使得代码更简洁,也更易于阅读和维护,但牺牲了一些控制力。

执行效率

有的同学可能对性能比较关心。就执行速度而言,for 和 foreach 循环的效率差异通常是微不足道的,特别是在现代编译器和解释器优化的情况下。但是,还是有一些细微的差别:

  • for循环:在某些情况下,for 循环可能略微更快,因为它的控制结构很简单(通常是一个索引和一个结束条件的比较)。如果你在循环中需要使用索引,或者你需要逆序遍历,或者以非标准的步长遍历,使用 for 循环可以直接满足这些需求而无需额外的计算或间接的访问。
  • foreach循环foreach 循环通常提供了对集合的简化访问,隐藏了迭代的细节。在一些语言中,foreach 循环背后可能使用了迭代器或者其他机制,这可能引入了轻微的性能开销。不过,对于只读操作或者不需要索引的情况,这个开销通常是可以忽略不计的。

在实际应用中,除非你正在编写非常性能敏感的代码,否则循环的选择应该更多地基于代码的清晰度和可维护性,而不是微小的性能差异。在大多数情况下,foreach 循环提供了更简洁、更易读的代码,尤其是当遍历集合而不需要索引时。

总结

for循环就像是多功能的瑞士军刀,适合于那些需要精确控制循环过程的场景。你可以自由地选择起点和终点,甚至可以逆向遍历或调整步长。

foreach循环则像是专一的榔头,对于简单地遍历集合来说,使用起来既快捷又高效。它让你免去了处理索引的烦恼,让你可以专注于元素本身。

编程不仅仅是关于写代码,更是关于选择合适的工具来解决问题。for和foreach就像是你工具箱里的两把锤子,它们各有所长,懂得在不同的情境下选择合适的一把,能让你的编程之路更加顺畅。

关注萤火架构,加速技术提升!