歡迎加入QQ討論群258996829
麥子學(xué)院 頭像
蘋果6袋
6
麥子學(xué)院

如何實現(xiàn)JavaScript的Map和Filter函數(shù)?

發(fā)布時間:2017-08-08 00:14  回復(fù):0  查看:2181   最后回復(fù):2017-08-08 00:14  
本文和大家分享的主要是JavaScript Map Filter 函數(shù)的實現(xiàn)相關(guān)內(nèi)容及其工作原理,一起來看看吧,希望對大家 學(xué)習(xí)javascript有所幫助。
   Array.map
  Array.map 通過對輸入的數(shù)組中每一個元素進(jìn)行變換,返回由變換后的元素按序組成的新數(shù)組。原始數(shù)組的值不會被修改。假設(shè)我們相對一個數(shù)組中的每一個元素乘以 3 ,使用 for 循環(huán)可以這樣寫。
   for循環(huán)
   var originalArr = [1, 2, 3, 4, 5]; var newArr = []; for( var i = 0; i < originalArr.length; i++) {
  newArr  = originalArr * 3;
  }console.log(newArr); // -> [3, 6, 9, 12, 15]
  接下來我們將這個for循環(huán)抽象成一個函數(shù)。
  multiplyByThree函數(shù)
  var originalArr = [1, 2, 3, 4, 5];function multiplyByThree(arr) {
  var newArr = [];
  for(var i = 0; i < arr.length; i++) {
  newArr = arr * 3;
  }
  return newArr;
  }var arrTransformed = multiplyByThree(originalArr);console.log(arrTransformed); // -> [3, 6, 9, 12, 15]
  現(xiàn)在我們繼續(xù)深化這個抽象思路,將multiplyByThree中對每一個元素乘以3部分抽象為一個新的函數(shù)。
  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 = timesThree(arr);
  }
  return newArr;
  }var arrTransformed = multiplyByThree(originalArr);console.log(arrTransformed); // -> [3, 6, 9, 12, 15]
  這樣有什么好處呢?設(shè)想如果我們想對每一個元素乘以5,或則10,我們還要把整個for循環(huán)寫一遍嗎!
  如果我們對timesThree函數(shù)稍作修改,就可以輕松的復(fù)用很多代碼。
  multiply函數(shù)
  我們將:
  function multiplyByThree(arr) {
  var newArr = [];
  for(var i = 0; i < arr.length; i++) {
  newArr = timesThree(arr);
  }
  return newArr;
  }
  重構(gòu)為:
  function multiply(arr, multiplyFunction) {
  var newArr = [];
  for(var i = 0; i < arr.length; i++) {
  newArr = multiplyFunction(arr);
  }
  return newArr;
  }
  我們將multiplyByThree重命名為multiply,并增加了一個參數(shù)。該參數(shù)是一個函數(shù),定義了數(shù)組元素的變換規(guī)則。通過定義一個timesThree函數(shù)來達(dá)到實現(xiàn)對每一個數(shù)組元素乘以3的目的。
  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]
  有何優(yōu)點呢?我們可以很簡單定義任何變換:
  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
  我們進(jìn)一步抽象:
  function multiply(arr, multiplyFunction) {
  var newArr = [];
  for(var i = 0; i < arr.length; i++) {
  newArr = multiplyFunction(arr);
  }
  return newArr;
  }
  將multiply改為map, multiplyFunction改為transform:
  function map(arr, transform) {
  var newArr = [];
  for(var i = 0; i < arr.length; i++) {
  newArr = transform(arr);
  }
  return newArr;
  }
  我們可以將任何對單個元素操作的函數(shù)傳入map函數(shù)。比如,我們將所有字符都變換成大寫:
  function makeUpperCase(str) {
  return str.toUpperCase();
  }var arr = ['abc', 'def', 'ghi'];var ARR = map(arr, makeUpperCase);console.log(ARR); // -> ['ABC', 'DEF, 'GHI']
  Array.map
  我們定義的map函數(shù)和原生的Array.map還是有區(qū)別的:數(shù)組不再需要作為第一個參數(shù)傳入,而是在點(.)的左側(cè)。如果使用我們定義的map函數(shù),如下:
  function func(item) {
  return item * 3;
  }var arr = [1, 2, 3];var newArr = map(arr, func);console.log(newArr); // -> [3, 6, 9]
  將其改寫為使用Array.map函數(shù)的形式:
  function func(item) {
  return item * 3;
  }var arr = [1, 2, 3];var newArr = arr.map(func);console.log(newArr); // -> [3, 6, 9]
  Arrary.map參數(shù)解析
  除了變換函數(shù)外,Array.map還可以接收其它兩個參數(shù)數(shù)組索引(index), 原始的數(shù)組。
  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']
  因此,你可以再變換函數(shù)中使用索引和原始的數(shù)組。比如:你想要將一個列表變?yōu)閹蛱柕牧斜恚瑒t需要使用索引(index)參數(shù):
  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"]
  因此,我們自己實現(xiàn)的map函數(shù)也應(yīng)該支持這兩個參數(shù):
  function map(arr, transform) {
  var newArr = [];
  for(var i = 0; i < arr.length; i++) {
  newArr = transform(arr, i, arr);
  }
  return newArr;
  }
  當(dāng)然,Array.map函數(shù)還有一些錯誤檢查和執(zhí)行優(yōu)化的代碼,我們定義的map只編碼了核心功能。
  Array.filter
  Array.filter將數(shù)組中不滿足條件的元素過濾,我們可以用for循環(huán)加上Array.push來實現(xiàn)。
  for-loop
  下面這段JS代碼將所有大于5的元素篩選出來:
  var arr = [2, 4, 6, 8, 10];var filteredArr = [];for(var i = 0; i < arr.length; i++) {
  if(arr > 5) {
  filteredArr.push(arr);
  }
  }console.log(filteredArr); // -> [6, 8, 10]
  我們可以抽象這段代碼,定義為一個函數(shù):
  function filterLessThanFive(arr) {
  var filteredArr = [];
  for(var i = 0; i < arr.length; i++) {
  if(arr > 5){
  filteredArr.push(arr);
  }
  }
  return filteredArr;
  }var arr1 = [2, 4, 6, 8, 10];var arr1Filtered = filterLessThanFive(arr1);console.log(arr1Filtered); // -> [6, 8, 10]
  進(jìn)一步抽象,將過濾條件抽出來:
  function isGreaterThan5(item) {
  return item > 5;
  }function filterLessThanFive(arr) {
  var filteredArr = [];
  for(var i = 0; i < arr.length; i++) {
  if(isGreaterThan5(arr)) {
  filteredArr.push(arr);
  }
  }
  return filteredArr;
  }var originalArr = [2, 4, 6, 8, 10];var newArr = filterLessThanFive(originalArr);console.log(newArr); // -> [6, 8, 10]
  將過濾條件函數(shù)作為參數(shù)傳入:
  function filterBelow(arr, greaterThan) {
  var filteredArr = [];
  for(var i = 0; i < arr.length; i++) {
  if(greaterThan(arr)) {
  filteredArr.push(arr);
  }
  }
  return filteredArr;
  }var originalArr = [2, 4, 6, 8, 10];
  大功告成!我們可以使用如下代碼來取出所有大于5的元素:
  function isGreaterThan5(item) {
  return item > 5;
  }var newArr = filterBelow(originalArr, isGreaterThan5);console.log(newArr); // -> [6, 8, 10];
  Array.filter
  我們將filterBelow重命名為filter, greaterThan重命名為testFunction:
  function filter(arr, testFunction) {
  var filteredArr = [];
  for(var i = 0; i < arr.length; i++) {
  if(testFunction(arr)) {
  filteredArr.push(arr);
  }
  }
  return filteredArr;
  }
  這就是一個基本的Array.filter函數(shù)了!
  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']
  同樣,Array.filter也有索引(index)和原始數(shù)組這兩個額外參數(shù)。
  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']
來源:SegmentFault
您還未登錄,請先登錄

熱門帖子

最新帖子

?