RError.com

RError.com Logo RError.com Logo

RError.com Navigation

  • 主页

Mobile menu

Close
  • 主页
  • 系统&网络
    • 热门问题
    • 最新问题
    • 标签
  • Ubuntu
    • 热门问题
    • 最新问题
    • 标签
  • 帮助
主页 / 问题 / 1177349
Accepted
Gretta
Gretta
Asked:2020-09-12 18:24:48 +0000 UTC2020-09-12 18:24:48 +0000 UTC 2020-09-12 18:24:48 +0000 UTC

ForEach vs Map vs Reduce 什么时候?

  • 772

面对我不明白什么时候什么时候应用这个方法的事实map,forEach我也经常遇到reduce,但不清楚他们为什么选择它而不是,例如,同一个map。

代码应该在什么map时候使用reduce,什么时候使用forEach?

他们的主要区别是什么?

javascript
  • 4 4 个回答
  • 10 Views

4 个回答

  • Voted
  1. Best Answer
    Vasily
    2020-09-12T18:45:44Z2020-09-12T18:45:44Z

    map、forEach和reduce方法确实有很多共同点,使用什么以及何时使用取决于您最终想要得到什么样的结果。

    假设我们有一个数组:

    const locations = [
      {country: "Россия", population: 10},
      {country: "Китай", population: 100},
      {country: "США", population: 20}
    ]
    

    如果我们只需要对数组的每个元素执行某个动作,那么forEach 方法就适合这里:

    locations.forEach(location => {
      console.log(location)
      // мы получим три вывода в консоль
      // по одному для каждой локации
      // {country: "Россия", population: 10}
      // {country: "Китай", population: 100}
      // {country: "США", population: 20}
    })
    
    // или так, если нам нужно только определенное значение
    
    locations.forEach(location => {
      console.log(location.country)
      // Россия
      // Китай
      // США
    })
    
    // или так, по количеству значений в массиве 
    
    locations.forEach(() => {
      console.log("Как дела?")
      // Как дела?
      // Как дела?
      // Как дела?
    })
    

    如果我们想转换我们的数组并将结果存储在一个变量中,那么map 方法将比 forEach 更合适,因为第一个方法会立即返回一个新数组。

    当我们需要在 HTML 标签中“包装”每个国家/地区名称时,让我们看看 forEach 与 map 的区别:

    // через forEach
    const result = []
    locations.forEach(location => {
      result.push(`<h1>${location.country}</h1>`)
    })
    console.log(result)
    // ["<h1>Россия</h1>", "<h1>Китай</h1>", "<h1>США</h1>"]
    
    // с использованием map
    const result = locations.map(location => `<h1>${location.country}</h1>`)    
    console.log(result)
    // ["<h1>Россия</h1>", "<h1>Китай</h1>", "<h1>США</h1>"]
    

    reduce 方法与 map 的不同之处在于它返回最终的“值”。

    假设我们要计算总人口规模:

    const result = locations.reduce((total, location) => {
      return total + location.population
    }, 0)
    
    console.log(result)
    // 130
    

    这是一个相当简单的例子,但是“最终值”不仅可以是一个数字,还可以是一个对象或一个数组,这使得 reduce 方法成为一个真正强大的转换工具。

    • 14
  2. OPTIMUS PRIME
    2020-09-12T21:03:54Z2020-09-12T21:03:54Z

    了解所有三种方法都只是看起来比常规循环更漂亮的内联循环是很有用的。如果您已经擅长使用循环,您只需要知道这些方法的作用,以便逐渐过渡到它们。

    ► forEach(正则枚举)

    let arr = [1, 2, 3];
    
    // --
    for (let i = 0; i < arr.length; i++) {
      console.log( "for", arr[i] );
    }
    
    // --
    arr.forEach( e => console.log("forEach", e) ); // e ←→ arr[i]

    ► map - 创建一个新数组,为原始数组的每个元素依次调用传递的函数。将此函数的调用结果添加到创建的数组中。

    let arr = [1, 2, 3];
    
    // --
    let result = [];
    for (let i = 0; i < arr.length; i++) {
      result.push( arr[i] * 2 );
    }
    console.log(result); // [2, 4, 6]
    
    // --
    console.log( arr.map( e => e * 2 ) ); // [2, 4, 6]

    ► reduce - 可用于除主要参数外,还需要一个额外变量的所有情况,该变量将在枚举过程中存储一些内容。

    let arr = [1, 2, 3];
    
    // --
    let sum = 0;
    for (let i = 0; i < arr.length; i++) {
      sum += arr[i];
    }
    console.log(sum); // 6
    
    // --                                         ↓ Вместо let sum = 0;
    console.log( arr.reduce( (sum, e) => sum + e, 0 ) ); // 6
    
    // Вместо объявления переменной sum, её можно встроить в одну строчку с вызовом.
    // Также вызывает функцию для каждого элемента.
    // То, что вернет функция - станет значением sum при следующем вызове функции.
    
    // В конце перебора вернет итоговое значение sum.


    并且“内部”发生了这样的事情:

    Array.prototype.my_forEach = function(fn, context) {
      for (let i = 0; i < this.length; i++) {
        fn.call(context, arr[i], i, arr);
      } // Переданная функция получает "имя" fn, и вызывается через неё в цикле.
    };
    
    Array.prototype.my_map = function(fn, context) {
      let result = [];
      for (let i = 0; i < this.length; i++) {
        result.push( fn.call(context, arr[i], i, arr) );
      } // в будущий массив добавляются результаты вызовов функции.
      
      return result;
    };
    
    Array.prototype.my_reduce = function(fn, value) {
      let i = 0;
      
      if (typeof value == "undefined") {
        if (this.length == 0) {
          throw new Error("Reduce of empty array with no initial value");
        }
        
        i = 1;
        value = this[0];
        // Если второй аргумент (объявление начального значения) не указан,
        // берется первый элемент массива вместо него.
      }
      
      for (i; i < this.length; i++) {
        value = fn(value, arr[i], i, arr);
      }
      
      return value;
    };
    
    /***/
    
    let arr = [1, 2, 3];
    
    arr.my_forEach( e => console.log(e) ); // 1, 2, 3
    
    console.log( arr.my_map( e => e * 2 ) ); // [2, 4, 6]
    
    console.log( arr.my_reduce( (sum, e) => sum + e ) ); // 6
    .as-console-wrapper { min-height: 100vh !important; }

    • 13
  3. vsemozhebuty
    2020-09-12T18:34:54Z2020-09-12T18:34:54Z

    简而言之:

    1. 当您需要更改当前数组或从其中一个一个地使用数据而不返回新值时,最好使用forEach()(或for-of循环)。示例:将数组的所有元素一一打印到控制台。

    2. 当您需要创建并返回一个具有相同数量元素但已更改它们的新数组时,最好使用map(). 示例:从字符串数组创建一个新的数字数组。

    3. 当您需要创建并返回完全不同的值(原始值或对象)时,在创建过程中迭代数组的元素时,最好使用reduce(). 示例:返回数组中所有数值元素的总和。

    • 4
  4. eri
    2020-09-12T18:31:12Z2020-09-12T18:31:12Z

    FOREACH - 当你有“面条代码”时,当循环体很简单时 - 2-5行。这个循环很容易阅读。

    而如果代码被分割成回调,那么body中的一切都是复杂的,你可以把它分成一个函数或者已经有一个函数——然后是map,reduce。

    MAP - 对每个元素应用一个函数。输出是一个相同长度的数组。

    REDUCE - 成对地从最后一次迭代中获取结果,并从数组中获取一个新元素。输出是一个变量。

    • 1

相关问题

  • 第二个 Instagram 按钮的 CSS 属性

  • 由于模糊,内容不可见

  • 弹出队列。消息显示不正确

  • 是否可以在 for 循环中插入提示?

  • 如何将 JSON 请求中的信息输出到数据表 Vuetify vue.js?

Sidebar

Stats

  • 问题 10021
  • Answers 30001
  • 最佳答案 8000
  • 用户 6900
  • 常问
  • 回答
  • Marko Smith

    如何从列表中打印最大元素(str 类型)的长度?

    • 2 个回答
  • Marko Smith

    如何在 PyQT5 中清除 QFrame 的内容

    • 1 个回答
  • Marko Smith

    如何将具有特定字符的字符串拆分为两个不同的列表?

    • 2 个回答
  • Marko Smith

    导航栏活动元素

    • 1 个回答
  • Marko Smith

    是否可以将文本放入数组中?[关闭]

    • 1 个回答
  • Marko Smith

    如何一次用多个分隔符拆分字符串?

    • 1 个回答
  • Marko Smith

    如何通过 ClassPath 创建 InputStream?

    • 2 个回答
  • Marko Smith

    在一个查询中连接多个表

    • 1 个回答
  • Marko Smith

    对列表列表中的所有值求和

    • 3 个回答
  • Marko Smith

    如何对齐 string.Format 中的列?

    • 1 个回答
  • Martin Hope
    Alexandr_TT 2020年新年大赛! 2020-12-20 18:20:21 +0000 UTC
  • Martin Hope
    Alexandr_TT 圣诞树动画 2020-12-23 00:38:08 +0000 UTC
  • Martin Hope
    Air 究竟是什么标识了网站访问者? 2020-11-03 15:49:20 +0000 UTC
  • Martin Hope
    Qwertiy 号码显示 9223372036854775807 2020-07-11 18:16:49 +0000 UTC
  • Martin Hope
    user216109 如何为黑客设下陷阱,或充分击退攻击? 2020-05-10 02:22:52 +0000 UTC
  • Martin Hope
    Qwertiy 并变成3个无穷大 2020-11-06 07:15:57 +0000 UTC
  • Martin Hope
    koks_rs 什么是样板代码? 2020-10-27 15:43:19 +0000 UTC
  • Martin Hope
    Sirop4ik 向 git 提交发布的正确方法是什么? 2020-10-05 00:02:00 +0000 UTC
  • Martin Hope
    faoxis 为什么在这么多示例中函数都称为 foo? 2020-08-15 04:42:49 +0000 UTC
  • Martin Hope
    Pavel Mayorov 如何从事件或回调函数中返回值?或者至少等他们完成。 2020-08-11 16:49:28 +0000 UTC

热门标签

javascript python java php c# c++ html android jquery mysql

Explore

  • 主页
  • 问题
    • 热门问题
    • 最新问题
  • 标签
  • 帮助

Footer

RError.com

关于我们

  • 关于我们
  • 联系我们

Legal Stuff

  • Privacy Policy

帮助

© 2023 RError.com All Rights Reserve   沪ICP备12040472号-5