深入理解 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;
});
深入理解 Array.prototype.map()的更多相关文章
- Javascript中Array.prototype.map()详解
map 方法会给原数组中的每个元素都按顺序调用一次 callback 函数.callback 每次执行后的返回值组合起来形成一个新数组. callback 函数只会在有值的索引上被调用:那些从来没被赋 ...
- Array.prototype.map()详解
今天在地铁上看到这样一个小例子: ["1","2","3"].map(parseInt); 相信很多人和我一样,觉得输出的结果是[1,2,3 ...
- js 数组map用法 Array.prototype.map()
map 这里的map不是"地图"的意思,而是指"映射".[].map(); 基本用法跟forEach方法类似: array.map(callback,[ thi ...
- Array.prototype.map()
mdn上解释的特别详细 概述 map() 方法返回一个由原数组中的每个元素调用一个指定方法后的返回值组成的新数组. 语法 array.map(callback[, thisArg]) 参数 callb ...
- Array.prototype.map()和Array.prototypefilter()
ES5 => 筛选功能 Array.prototypefilter(): 代码: var words = ['spray', 'limit', 'elite', 'exuberant', 'd ...
- javascript的Array.prototype.map()和jQuery的jQuery.map()
两个方法都可以根据现有数组创建新数组,但在使用过程中发现有些不同之处 以下面这个数据为例: var numbers = [1, 3, 4, 6, 9]; 1. 对undefined和null的处理 a ...
- Array.prototype.map()方法详解
Array.prototype.map() 1 语法 const new_array = arr.map(callback[, thisArg]) 2 简单栗子 let arr = [1, 5, 10 ...
- javascript 一些函数的实现 Function.prototype.bind, Array.prototype.map
* Function.prototype.bind Function.prototype.bind = function() { var self = this, context = [].shift ...
- 理解Array.prototype.slice.call(arguments)
在很多时候经常看到Array.prototype.slice.call()方法,比如Array.prototype.slice.call(arguments),下面讲一下其原理: 1.基本讲解 1.在 ...
随机推荐
- ssh Jetson tk1
背景: 因为TK1要放到智能车上,不方便打开roscore和各个节点,因此需要PC远程控制. 方法: 在PC端用ssh命令登录: (1)命令sudo ssh tegra-ubuntu.local(te ...
- 【windows核心编程】双机调试操作
1.1 中断与异常 计算机最重要的任务就是执行指令,只要你设置一个起始位置,他就会一条指令的执行下去.而中断和异常机制是为了防止计算机无休止地执行任意指令,出现错误时可以引导处理器转向正常控制流而诞生 ...
- linux服务器last查看关机记录
1.查看重启记录 last reboot命令 [root@test ~]# last reboot reboot system boot -.el6.x Mon May : - : (+:) rebo ...
- [ VB ] If 运算符 [ C# ] 条件运算符 (?:)
//保留了原文 ()为大概的意思 VB で使用していた IIf 関数の代わりに VB2008 からは If 演算子 を使用可能となった. また. C# では.条件演算子 (?:) で同等の記述が可 ...
- CSS选择器中带点(.)怎么办?
在SharePoint中很多元素的ID都用点(.)来连接的,比如: <li class="ms-cui-group" id="Ribbon.Documents.Ed ...
- Project Euler Problem 10
Summation of primes Problem 10 The sum of the primes below 10 is 2 + 3 + 5 + 7 = 17. Find the sum of ...
- Android通讯:通话
Android通讯之通话功能的实现: 在Android中,android.telephony.TelephonyManager对象是开发者获取当前通话网络相关信息的窗口,通过TelephonyMana ...
- Linux常用命令3(压缩和解压缩总结)
tar命令 解包:tar zxvf FileName.tar 打包:tar czvf FileName.tar DirName gz命令 解压1:gunzip FileName.gz 解压2:gzip ...
- 解决报错SAXNotRecognizedException: Feature 'http://javax.xml.XMLConstants/feature/secure-processing' not recognized
今天调试appium脚本,发现运行脚本就报错 SAXNotRecognizedException: Feature 'http://javax.xml.XMLConstants/feature/sec ...
- laravel 事件广播
Laravel 5.1 之中新加入了事件广播的功能,作用是把服务器中触发的事件通过websocket服务通知客户端,也就是浏览器,客户端js根据接受到的事件,做出相应动作.本文会用简单的代码展示一个事 ...