# 如何实现JavaScript的Map和Filter函数？

## Array.map

`Array.map`通过对输入的数组中每一个元素进行变换，返回由变换后的元素按序组成的新数组。原始数组的值不会被修改。假设我们相对一个数组中的每一个元素乘以3，使用`for`循环可以这样写。

### for循环

var originalArr = [1, 2, 3, 4, 5];var newArr = [];for(var i = 0; i < originalArr.length; i++) { newArr[i] = originalArr[i] * 3;}console.log(newArr); // -> [3, 6, 9, 12, 15]

### multiplyByThree函数

var originalArr = [1, 2, 3, 4, 5];function multiplyByThree(arr) { var newArr = []; for(var i = 0; i < arr.length; i++) { newArr[i] = arr[i] * 3; } return newArr;}var arrTransformed = multiplyByThree(originalArr);console.log(arrTransformed); // -> [3, 6, 9, 12, 15]

var originalArr = [1, 2, 3, 4, 5];function timesThree(item) { return item * 3;}function multiplyByThree(arr) { var newArr = []; for(var i = 0; i < arr.length; i++) { newArr[i] = timesThree(arr[i]); } return newArr;}var arrTransformed = multiplyByThree(originalArr);console.log(arrTransformed); // -> [3, 6, 9, 12, 15]

### multiply函数

function multiplyByThree(arr) { var newArr = []; for(var i = 0; i < arr.length; i++) { newArr[i] = timesThree(arr[i]); } return newArr;}

function multiply(arr, multiplyFunction) { var newArr = []; for(var i = 0; i < arr.length; i++) { newArr[i] = multiplyFunction(arr[i]); } return newArr;}

var originalArr = [1, 2, 3, 4, 5];function timesThree(item) { return item * 3;}var arrTimesThree = multiply(originalArr, timesThree);console.log(arrTimesThree); // -> [3, 6, 9, 12, 15]

var originalArr = [1, 2, 3, 4, 5];function timesFive(item) { return item * 5;}var arrTimesFive = multiply(originalArr, timesFive);console.log(arrTimesFive); // -> [5, 10, 15, 20, 25]

### Map

function multiply(arr, multiplyFunction) { var newArr = []; for(var i = 0; i < arr.length; i++) { newArr[i] = multiplyFunction(arr[i]); } return newArr;}

`multiply`改为`map`, `multiplyFunction`改为`transform`:

function map(arr, transform) { var newArr = []; for(var i = 0; i < arr.length; i++) { newArr[i] = transform(arr[i]); } return newArr;}

function makeUpperCase(str) { return str.toUpperCase();}var arr = ['abc', 'def', 'ghi'];var ARR = map(arr, makeUpperCase);console.log(ARR); // -> ['ABC', 'DEF, 'GHI']

### Array.map

function func(item) { return item * 3;}var arr = [1, 2, 3];var newArr = map(arr, func);console.log(newArr); // -> [3, 6, 9]

function func(item) { return item * 3;}var arr = [1, 2, 3];var newArr = arr.map(func);console.log(newArr); // -> [3, 6, 9]

### Arrary.map参数解析

function logItem(item) { console.log(item);}function logAll(item, index, arr) { console.log(item, index, arr);}var arr = ['abc', 'def', 'ghi'];arr.map(logItem); // -> 'abc', 'def', 'ghi'arr.map(logAll); // -> 'abc', 0, ['abc', 'def', 'ghi'] // -> 'def', 1, ['abc', 'def', 'ghi'] // -> 'ghi', 2, ['abc', 'def', 'ghi']

function multiplyByIndex(item, index) { return (index + 1) + '. ' + item;}var arr = ['bananas', 'tomatoes', 'pasta', 'protein shakes'];var mappedArr = arr.map(multiplyByIndex);console.log(mappedArr); // ->// ["1. bananas", "2. tomatoes", "3. pasta", "4. protein shakes"]

function map(arr, transform) { var newArr = []; for(var i = 0; i < arr.length; i++) { newArr[i] = transform(arr[i], i, arr); } return newArr;}

## Array.filter

`Array.filter`将数组中不满足条件的元素过滤，我们可以用for循环加上`Array.push`来实现。

### for-loop

var arr = [2, 4, 6, 8, 10];var filteredArr = [];for(var i = 0; i < arr.length; i++) { if(arr[i] > 5) { filteredArr.push(arr[i]); }}console.log(filteredArr); // -> [6, 8, 10]

function filterLessThanFive(arr) { var filteredArr = []; for(var i = 0; i < arr.length; i++) { if(arr[i] > 5){ filteredArr.push(arr[i]); } } return filteredArr;}var arr1 = [2, 4, 6, 8, 10];var arr1Filtered = filterLessThanFive(arr1);console.log(arr1Filtered); // -> [6, 8, 10]

function isGreaterThan5(item) { return item > 5;}function filterLessThanFive(arr) { var filteredArr = []; for(var i = 0; i < arr.length; i++) { if(isGreaterThan5(arr[i])) { filteredArr.push(arr[i]); } } return filteredArr;}var originalArr = [2, 4, 6, 8, 10];var newArr = filterLessThanFive(originalArr);console.log(newArr); // -> [6, 8, 10]

function filterBelow(arr, greaterThan) { var filteredArr = []; for(var i = 0; i < arr.length; i++) { if(greaterThan(arr[i])) { filteredArr.push(arr[i]); } } return filteredArr;}var originalArr = [2, 4, 6, 8, 10];

function isGreaterThan5(item) { return item > 5;}var newArr = filterBelow(originalArr, isGreaterThan5);console.log(newArr); // -> [6, 8, 10];

### Array.filter

function filter(arr, testFunction) { var filteredArr = []; for(var i = 0; i < arr.length; i++) { if(testFunction(arr[i])) { filteredArr.push(arr[i]); } } return filteredArr;}

var arr = ['abc', 'def', 'ghijkl', 'mnopuv'];function longerThanThree(str) { return str.length > 3;}var newArr1 = filter(arr, longerThanThree);var newArr2 = arr.filter(longerThanThree);console.log(newArr1); // -> ['ghijkl', 'mnopuv']console.log(newArr2); // -> ['ghijkl', 'mnopuv']

function func(item, index, arr) { console.log(item, index, arr);}var arr = ['abc', 'def', 'ghi'];arr.filter(func); // -> 'abc', 0, ['abc', 'def', 'ghi'] // -> 'def', 1, ['abc', 'def', 'ghi'] // -> 'ghi', 2, ['abc', 'def', 'ghi']

```版权声明:

https://blog.fundebug.com/2017/07/26/master_map_filter_by_hand_written/```

.copyright * { box-sizing: border-box; }

0 条评论

• ### JavaScript面试的完美指南(开发者视角)

函数是 JavaScript 的精华，是 JS 一等公民。JS 函数不仅仅是一个普通的函数，与其他语言不同，JS 函数可以赋值给变量，作为参数传递给另一个函数，...

• ### 10个JavaScript难点

为了保证可读性，本文采用意译而非直译，并且对示例代码进行了大量修改。另外，本文版权归原作者所有，翻译仅用于学习。

• ### 10个最佳ES6特性

原文: Top 10 ES6 Features Every Busy JavaScript Developer Must Know

• ### Flux 架构入门教程

过去一年中，前端技术大发展，最耀眼的明星就是React。 React 本身只涉及UI层，如果搭建大型应用，必须搭配一个前端框架。也就是说，你至少要学两样东西，才...

• ### CSS 3.0粘性定位的妙用

position:sticky是 CSS 3.0新增的定位属性，可以说是相对定位relative和固定定位fixed的结合，它主要用在对scroll事件的监听上...

• ### 高考啦！ JavaScript高考全国卷

HTML5学堂-码匠：一年一度的高考~走过路过不要错过，做程序的你，来考考前端“高考题”吧！ 高考啦！！！ 全国卷 第1题 如下代码的运行结果是？ [ ] + ...

• ### vim的几种模式mode和按键映射map

这里把c映射成了a，在map生效的情况下，按下c就等同于按下了a 当然，常用的Ctrl,Shift,Alt自然也是支持的。

• ### 让vim更好用的基础配置

vim 这个上古神器时至今日，依然宝刀不老，拥护者众多。即使现代化的各种IDE，编辑器层出不穷，vim 依然是你大爷，就如最近周杰伦的超话榜一样，时光荏苒，你大...

• ### 监听DIV等标记的class属性改变，实现onshow,onhide

貌似h5标记有click等事件的监听，没有show,hide等事件的监听。用了一个tab样式库，想实现切换tab时刷新页面数据，这个库也没说明招接口也不好找。看...

Fundebug技术总监