zoukankan      html  css  js  c++  java
  • 深入理解 Array.prototype.map()

    深入理解 Array.prototype.map()

    map() 方法创建一个新数组,其结果是该数组中的每个元素都调用一个提供的函数后返回的结果。

    语法

    let new_array = arr.map(function callback(currentValue, index, array) { 
        // Return element for new_array 
    }[, thisArg])
    

    参数

    • callback 生成新数组元素的函数,使用三个参数:
      • currentValue 数组中正在处理的当前元素。
      • index 数组中正在处理的当前元素的索引。
      • array map 方法被调用的数组。
    • thisArg 可选的。执行 callback 函数时 使用的this 值。

    实际应用

    使用指定的方法对数组做批处理

    原理

    var numbers = [1, 4, 9];
    var roots = numbers.map(Math.sqrt);
    console.log(numbers) // [1, 4, 9]
    console.log(roots) // [1, 2, 3]
    

    封装

    var numbers = [1, 4, 9];
    const arrBat = (arr, func) => arr.map(func)
    var roots = arrBat(numbers, Math.sqrt)
    console.log(numbers) // [1, 4, 9]
    console.log(roots) // [1, 2, 3]
    

    只需要传入对应的处理方法,即可对数组所有元素做批处理。

    当然也可对此方法进行二次封装:

    var numbers = [1, 4, 9];
    
    const arrBat = (arr, func) => arr.map(func)
    const arrToSqrt = (arr) => arrBat(arr, Math.sqrt) // 开平方根
    const arrToSquare = (arr) => arrBat(arr, e => Math.pow(e, 2)) // 平方
    const arrToRound = (arr) => arrBat(arr, Math.round) // 四舍五入
    const arrToCeil = (arr) => arrBat(arr, Math.ceil) // 求上整
    const arrToFloor = (arr) => arrBat(arr, Math.floor) // 求下整
    const arrToDouble = (arr) => arrBat(arr, e => 2 * e) // 求倍数
    
    arrToSquare(numbers) // [1, 16, 81]
    arrToSqrt(numbers) // [1, 2, 3]
    

    多参数函数批量转化的误区

    先看下面一个方法:

    ["1", "2", "3"].map(parseInt);
    

    第一反应,这里应该返回的是 [1, 2, 3],然而,实际上返回的却是 [1, NaN, NaN]

    这是为什么呢?

    事实上,parseInt 接收两个参数,第一个是原始值,第二个是进制值,通常我们使用 parseInt('5') 类似的操作,实际上是默认第二参数为 10,。但注意,在 map 回调函数中,有三个参数,第一个是遍历出来的每一个元素,第二参数为遍历出的元素的下标,第三参数为调用者本身。这里, parseInt 接到了 map 的前两个参数,也就是元素和下标,第三参数被忽略,parseInt 把传过来的索引值当成进制数来使用,从而返回了NaN。

    正确的做法是:

    const arrToInt = str => Array.prototype.map.call(str, e => parseInt(e, 10))
    arrToInt("57832") // [5, 7, 8, 3, 2]
    arrToInt([1.2, 3.4, 9.6]) // [1, 3, 9]
    

    parseInt 不同,下面的结果会返回浮点数或指数 :

    ['1.1', '2.2e2', '3e300'].map(Number); // [1.1, 220, 3e+300]
    

    使用 map 重新格式化数组中的对象

    原理

    var kvArray = [{key: 1, value: 10}, {key: 2, value: 20}, {key: 3, value: 30}]
    
    var reformattedArray = kvArray.map(function(obj) { 
       var rObj = {};
       rObj[obj.key] = obj.value;
       return rObj;
    });
    // [{1: 10}, {2: 20}, {3: 30}], 
    

    封装

    var kvArray = [{key: 1, value: 10}, {key: 2, value: 20}, {key: 3, value: 30}]
    
    kvArrayToObjArray = (obj) => obj.map(e => {
      var rArr = [];
      rArr.push(e.key, e.value);
      return rArr;
    })
    
    var reformattedArray = kvArrayToObjArray(kvArray)
    // [[1, 10], [2, 20], [3, 30]]
    

    反转字符串

    原理

    var str = 'Hello';
    Array.prototype.map.call(str, function(x) {
      return x;
    }).reverse().join(''); // 'olleH'
    

    封装

    const reverseStr = str => Array.prototype.map.call(str, e => e).reverse().join('')
    c = reverseStr('Hello') // 'olleH'
    

    当然,还有一个更简单的反转字符串方法,使用 ES6 的解构即可

    const reverseString = str => [...str].reverse().join('');
    
    reverseString('foobar') // 'raboof'
    

    将字符串转换为 ASCII 码

    原理

    var a = Array.prototype.map.call("Hello World", function(x) { 
      return x.charCodeAt(0); 
    })
    // [72, 101, 108, 108, 111, 32, 87, 111, 114, 108, 100]
    

    封装

    const strToAscii = str => Array.prototype.map.call(str, e => e.charCodeAt(0))
    strToAscii("Hello World") // [72, 101, 108, 108, 111, 32, 87, 111, 114, 108, 100]
    

    DOM 操作

    甚至可以使用 map 对 DOM 进行操作

    var elems = document.querySelectorAll('select option:checked');
    var values = Array.prototype.map.call(elems, function(obj) {
      return obj.value;
    });
    
  • 相关阅读:
    C# String.Compare 方法测试
    C#checked 与 unchecked
    C#枚举类型
    C#结构体
    C越界和溢出的区别
    python/matlab : 将txt文件中的数据读为numpy数组
    matlab程序里调用python文件
    Python
    Pycharm调试及快捷键技巧
    Pycharm远程连接服务器debug时报错
  • 原文地址:https://www.cnblogs.com/xiaoyulive/p/8567347.html
Copyright © 2011-2022 走看看