重学JS|JS高阶方法(map,reduce,filter)

map、reduce 和 filter 是三个非常实用的 JavaScript 数组方法,赋予了开发者四两拨千斤的能力。我们直接进入正题,看看如何使用(并记住)这些的方法!


Array.map() return arr

[x1, x2, x3, x4].reduce(f) = [f(x1),f(x2),f(x3),f(x4)]//这里f接收的值可以多个,

Array.map() 根据传递的转换函数,更新给定数组中的每个值,并返回一个相同长度的新数组。它接受一个回调函数作为参数,用以执行转换过程。

  let newArray = oldArray.map((value, index, array) => {
      ...
    });

一个帮助记住 map 的方法:Morph Array Piece-by-Piece(逐个改变数组)
你可以使用 map 代替 for-each 循环,来遍历并对每个值应用转换函数。这个方法适用于当你想更新数组的同时保留原始值。它不会潜在地删除任何值(filter 方法会),也不会计算出一个新的输出(就像 reduce 那样)。map 允许你逐个改变数组。一起来看一个例子:

[1, 4, 6, 14, 32, 78].map(val => val * 10)
// the result is: [10, 40, 60, 140, 320, 780]

上面的例子中,我们使用一个初始数组([1, 4, 6, 14, 32, 78]),映射每个值到它自己的十倍(val * 10)。结果是一个新数组,初始数组的每个值被这个等式转换:[10, 40, 60, 140, 320, 780]。

求数组的平方

'use strict';
function pow(x) {
    return x * x;
}
var arr = [1, 2, 3, 4, 5, 6, 7, 8, 9];
var results = arr.map(pow); // [1, 4, 9, 16, 25, 36, 49, 64, 81]
console.log(results);

数组字符串化

var arr = [1, 2, 3, 4, 5, 6, 7, 8, 9];
arr.map(String); // ['1', '2', '3', '4', '5', '6', '7', '8', '9']

Array.filter() return arr

filter() 方法创建一个新的数组,新数组中的元素是通过检查指定数组中符合条件的所有元素。
注意: filter() 不会对空数组进行检测。
注意: filter() 不会改变原始数组。
[x1, x2, x3, x4].reduce(f) = [f(x1),f(x2),f(x3),f(x4)];
//看起来和map以及every差不多,其实也是,不同在于,他的作用如其名 过滤器。结果数组个数 <=4;

function(currentValue, index,arr)//回调函数
currentValue: 必须。当前元素的值
index: 可选。当前元素的索引值
arr: 可选。当前元素属于的数组对象

类似搜索过滤器,filter 基于传递的参数来过滤出值。
举个例子,假定有个数字数组,想要过滤出大于 10 的值,可以这样写:

[1, 4, 6, 14, 32, 78].filter(val => val > 10)
// the result is: [14, 32, 78]

但是 filter 方法,只返回真值。因此如果所有值都执行指定的检查的话,结果的长度会小于等于原始数组。
把 filter 想象成一个漏斗。部分混合物会从中穿过进入结果,而另一部分则会被留下并抛弃。

假设宠物训练学校有一个四只狗的小班,学校里的所有狗都会经过各种挑战,然后参加一个分级期末考试。我们用一个对象数组来表示这些狗狗:

const students = [
  { name: "Boops",
     finalGrade: 80
  },{
    name: "Kitten",
    finalGrade: 45
  },{
    name: "Taco",
    finalGrade: 100
  }, {
    name: "Lucy",
    finalGrade: 60
  }
]

如果狗狗们的期末考试成绩高于 70 分,它们会获得一个精美的证书;反之,它们就要去重修。为了知道证书打印的数量,要写一个方法来返回通过考试的狗狗。不必写循环来遍历数组的每个对象,我们可以用 filter 简化代码!

const passingDogs = students.filter((student) => {
  return student.finalGrade >= 70
})
/*
passingDogs = [
  {
    name: "Boops",
    finalGrade: 80
  },
  {
    name: "Taco",
    finalGrade: 100
  }
]
*/

你也看到了,Boops 和 Taco 是好狗狗(其实所有狗都很不错),它们取得了通过课程的成就证书!利用箭头函数的隐式返回特性,一行代码就能实现。因为只有一个参数,所以可以删掉箭头函数的括号:


```javascript
const passingDogs = students.filter(student => student.finalGrade >= 70)

    /*
    passingDogs = [
      {
        name: "Boops",
        finalGrade: 80
      },
      {
        name: "Taco",
        finalGrade: 100
      }
    ]
    */

用处1:利用indexOf去重

let arr1= ['apple',  'banana', 'pear', 'apple', 'orange', 'orange'];
let arr2;
arr2 = arr1.filter((item, index, arr) => {
    return arr.indexOf(item) === index;
});

关键点:indexOf 总是返回数组中第一个元素的位置,后续的重复元素位置与返回的第一个元素的位置不相等,因此滤掉了。

reutrn s && s.trim();//返回非空值
reutrn s%2 !== 0;//返回奇数

Array.reduce()//reduce为降低、简化之意 return Number/String

mdn的意思

  [x1, x2, x3, x4].reduce(f) = f(f(f(x1, x2), x3), x4)//注意要理解累加器的概念,

reduce() 方法接受一个数组作为输入值并返回一个值。这点挺有趣的。reduce 接受一个回调函数,回调函数参数包括一个累计器(数组每一段的累加值,它会像雪球一样增长),当前值,和索引。reduce 也接受一个初始值作为第二个参数:

let finalVal = oldArray.reduce((accumulator, currentValue, currentIndex, array) => {
  ...
}), initalValue;

来写一个炒菜函数和一个作料清单:
// our list of ingredients in an array
const ingredients = ['wine', 'tomato', 'onion', 'mushroom']

// a cooking function
const cook = (ingredient) => {
  return `cooked ${ingredient}`
}

如果我们想要把这些作料做成一个调味汁(开玩笑的),用 reduce() 来归约!

const wineReduction = ingredients.reduce((sauce, item) => {
  return sauce += cook(item) + ', '
}, '')

// wineReduction = "cooked wine, cooked tomato, cooked onion, cooked mushroom, "

初始值(这个例子中的 ‘’)很重要,它决定了第一个作料能够进行烹饪。这里输出的结果不太靠谱,自己炒菜时要当心。下面的例子就是我要说到的情况:

const wineReduction = ingredients.reduce((sauce, item) => {
  return sauce += cook(item) + ', '
})

// wineReduction = "winecooked tomato, cooked onion, cooked mushroom, "

最后,确保新字符串的末尾没有额外的空白,我们可以传递索引和数组来执行转换:

const wineReduction = ingredients.reduce((sauce, item, index, array) => {
  sauce += cook(item)
  if (index < array.length - 1) {
    sauce += ', '
  }
  return sauce
}, '')

// wineReduction = "cooked wine, cooked tomato, cooked onion, cooked mushroom"

可以用三目操作符、模板字符串和隐式返回,写的更简洁(一行搞定!):

    const wineReduction = ingredients.reduce((sauce, item, index, array) => {
      return (index < array.length - 1) ? sauce += `${cook(item)}, ` : sauce += `${cook(item)}`
    }, '')
    
    // wineReduction = "cooked wine, cooked tomato, cooked onion, cooked mushroom"


*//计算每个元素出现的次数*

    var names = ['Alice', 'Bob', 'Tiff', 'Bruce', 'Alice'];
    
    var countedNames = names.reduce(function (allNames, name) { 
      if (name in allNames) {//检测name是否匹配allNames的key
        allNames[name]++;
      }
      else {
        allNames[name] = 1;
      }
      return allNames;
    }, {});
    // countedNames is:
    // { 'Alice': 2, 'Bob': 1, 'Tiff': 1, 'Bruce': 1 }

//数组去重

let arr = [1,2,1,2,3,5,4,5,3,4,4,4,4];
let result = arr.sort().reduce((init, current) => {//必须先排序
    if(init.length === 0 || init[init.length-1] !== current) {
        init.push(current);
    }
    return init;
}, []);
console.log(result); //[1,2,3,4,5]
// 你也可以使用set去重
const set = new Set([...[1,2,3],...[2,3,4]])
set //Set(4) {1, 2, 3, 4}
//最后将set变为数组
Array.from(set) //[1, 2, 3, 4]
[...set] //[1, 2, 3, 4]

//数组求和

function sum(arr) {
    return arr.reduce(function (x, y) {
        return x + y;
    });
}
sum([1, 2, 3, 4, 5]); // 15

//变整数

var arr = [1, 3, 5, 7, 9];
arr.reduce(function (x, y) {
return x * 10 + y;
}); // 13579

参考掘金的一篇文章

  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 2
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值