常用数组方法

JavaScript中对数组有四种常见的操作:map、filter、reduce、find。
ArrayMethods.png

map(映射)

Array.prototype.map() 将提供的转换应用于原始数组的每个元素,创建一个新数组。结果数组长度和原数组相同,并且根据提供的函数转换了元素。

  1. const arr = [1, 2, 3];
  2. const double = x => x * 2;
  3. arr.map(double);
  4. > [2, 4, 6]

filter(过滤)

Array.prototype.filter() 使用过滤函数创建新数组,以仅保留 true 基于该函数返回的元素。结果是一个等于或小于原始数组长度的数组,其中包含与原始数组相同元素的子集。

  1. const arr = [1, 2, 3];
  2. const isOdd = x => x % 2 === 1;
  3. arr.filter(isOdd);
  4. > [1, 3]

reduce(汇总)

Array.prototype.reduce() 在每个数组元素上运行函数,以生成(减少它)单个值。根据提供的reducer函数,结果可以是任何类型,例如整数,对象或数组。

  1. const arr = [1, 2, 3];
  2. const sum = (x, y) => x + y;
  3. arr.reduce(sum, 0);
  4. > 6
  5. const increment = (x, y) => [...x, x[x.length - 1] + y];
  6. arr.reduce(increment, [0]);
  7. > [0, 1, 3, 6]

find(查找)

Array.prototype.find() 返回匹配器函数返回的第一个元素true。结果是原始数组中的单个元素。

  1. const arr = [1, 2, 3];
  2. const isOdd = x => x % 2 === 1;
  3. arr.find(isOdd);
  4. > 1

应用

从对象数组中取出特定字段组成新数组

  1. var arr = [{
  2. 'id': '1',
  3. 'name': 'img1',
  4. 'imgUrl': './img1.jpg',
  5. },
  6. {
  7. 'id': '2',
  8. 'name: 'img2',
  9. 'imgUrl': './img2.jpg',
  10. },
  11. {
  12. 'id': '3',
  13. 'name': 'img3',
  14. 'imgUrl': './img3.jpg',
  15. }];
  16. // 取imgUrl生成新数组
  17. var imgList = arr.map(x => {return x.imgUrl})

从对象数组中按id查找对象

  1. myArray = [{'id':'73','foo':'bar'},{'id':'45','foo':'bar'}]
  2. // 获取对应的foo属性
  3. myArray.find(x => x.id === '45').foo;
  4. > "bar"
  5. // 查找索引
  6. myArray.findIndex(x => x.id === '45');
  7. > 1
  8. // 获取匹配的元素
  9. myArray.filter(x => x.id === '45');
  10. > [{id: "45", foo: "bar"}]
  11. // 获取一组foo属性
  12. myArray.filter(x => x.id === '45').map(x => x.foo);
  13. > ["bar"]

reduce() 求笛卡尔积

  1. const arr1 = ['1', '2', '3'];
  2. const arr2 = ['a', 'b'];
  3. // 用来作为运算的二维数组
  4. const arr3 = [arr1, arr2, ['x', 'y']]
  5. const result = arr3.reduce((last, el) => {
  6. const arr = [];
  7. // last:上次运算结果
  8. // el:数组中的当前元素
  9. last.forEach(e1 => {
  10. el.forEach(e2 => {
  11. arr.push(e1 + "_" + e2)
  12. })
  13. })
  14. return arr
  15. });
  16. console.log(result);

ES5 实现

map

  • ES5 实现map ```javascript var numbersA = [1,2,3,4,5,6]; var numbersB = [];

for(var i = 0; i < numbersA.length; i++){ numbersB.push(numbersA[i] * 2); } console.log(numbersB)

  1. - ES6
  2. ```javascript
  3. var numbersB = numbersA.map(item => {
  4. return item * 2;
  5. })
  6. console.log(numbersB)

filter

  • ES5 实现filter

    1. var persons = [
    2. {name:"小王",type:"boy",city:"广西",age:15,height:170},
    3. {name:"小美",type:"girl",city:"北京",age:16,height:180},
    4. {name:"小高",type:"girl",city:"湖南",age:18,height:175},
    5. {name:"小刘",type:"boy",city:"河北",age:20,height:177}
    6. ]
    7. // ES5,假定要拿person数组对象中类型为boy的对象
    8. var filterPersons = [];
    9. for(var i = 0; i < persons.length; i++){
    10. if (persons[i].type == "boy"){
    11. filterPersons.push(persons[i]); // 若是想要拿到对象的键值,直接persons[i].属性名
    12. }
    13. }
    14. console.log(filterPersons);
  • ES6

    1. var filterPersons = persons.filter( item => {
    2. return item.type === "boy";
    3. })

    find

  • ES5 实现 find ```javascript / 找到learnWebs数组对象中name值为segementdefault / var learnWebs = [ {name:”segmentdefault”}, {name:”MDN”}, {name:”stackoverflow”}, {name:”v2ex”}, {name:”w3cplus”}, {name:”segmentdefault”} ]

var learnWeb = []; for(var i = 0;i < learnWebs.length; i++){ if(learnWebs[i].name === “segmentdefault”){ learnWeb.push(learnWebs[i]); //break;// 若不加break,都会走完一遍for循环 } } console.log(learnWeb);

  1. - ES6 写法
  2. ```javascript
  3. var learnWeb = learnWebs.find(item => {
  4. return item.name === "segmentdefault";
  5. })

性能比较

性能上:for循环 > forEach > map
可读性:forEach/map > for循环

区别

for循环是按顺序遍历,按照下标索引的方式进行读取访问元素的,随机访问。
而forEach/map等是使用iterator迭代器进行遍历,先取到数组中的每一项的地止放入到队列中,然后按顺序取出队里的地址来访问元素。

可以使用 console.time() 以及 console.timeEnd() 进行测试。

扩展

forEach,map,filter,find 还有 every, some 方法都是不改变原有数组的,

  • forEach方法没有返回值,默认返回值为undefined,所以它不支持链式调用
  • map,filter方法会返回一个新的数组。
  • find方法返回的根据迭代器函数结果boolean值,若结果为真则返回指定的元素,若无则返回undefined

改变原有数组的有:增加(push,unshift),删除(pop,shift),reverse(颠倒,sort(排序),splice