簡約強大數組操做組合

前言

在實際js開發中對數組操做頻率很是高,看過一些小夥伴的一些用法,挺有意思,在這裏小記(不全)一下,備忘。webpack

array-combination

5個迭代方法:every、filter、forEach、map和some

  • every():對數組中的每一項運行給定函數,若是該函數每一項都返回true,則返回true
  • filter():對數組中的每一項運行給定函數,返回該函數會返回true的項組成的數組;
  • forEach():對數組中的每一項運行給定函數,這個方法沒有返回值;
  • map():對數組中的每一項運行給定函數,返回每次函數調用的結果組成的數組;
  • some():對數組中的每一項運行給定函數,若是該函數任意一項返回true,則返回true
// every
var numbers = [1, 2, 3, 4, 5, 6, 7];
var everyResult = numbers.every(function (item, index, array) {
  return (item > 2);
});
console.log(everyResult); // false

// some
someResult = numbers.some(function (item, index, array) {
  return (item > 2);
});
console.log(someResult); // true

// filter
var filterResult = numbers.filter(function (item, index, array) {
  return (item > 2);
});
console.log(filterResult); // [3, 4, 5, 6, 7]

// map
var mapResult = numbers.map(function (item, index, array) {
  return item * 2;
});
console.log(mapResult); // [2, 4, 6, 8, 10, 12, 14]

被忽視的 map 的第二個、第三個參數

一般狀況下, map 方法中的 callback 函數只接受一個參數,就是正在被遍歷數組元素自己。但不意味着 map 只給 callback 傳一個參數,這種慣性思惟極可能會讓咱們犯錯。下面舉一個例子:web

下面語句返回什麼呢: ['1', '2', '3'].map(parseInt)

可能你會以爲是 [1, 2, 3],但實際結果是 [1, NaN, NaN]segmentfault

map 回調方法 callback(currentValue, index, array) 有三個參數,第一個是數組中正在處理的當前元素,第二個是當前元素索引,第三個是數組自己。數組

Number.parseInt(string[, radix])有兩個參數,第一個是待轉化字符,第二個是進制數。parseInt傳入第三個參數會被忽略。svg

所以,上述執行函數

parseInt('1', 0, ['1', '2', '3']) // 1
parseInt('2', 1, ['1', '2', '3']) // NaN
parseInt('3', 2, ['1', '2', '3']) // NaN

拓展 map 在實際項目中的應用

匹配查找某個目錄下的文件並引入。ui

context.require 返回一個 require 函數:spa

function webpackContext(req) {
  return __webpack_require__(webpackContextResolve(req));
}

該函數有一個 keys 屬性,是一個函數,返回一個數組,該數組是由全部可能被上下文模塊的請求對象組成。code

let requireAll = requireContext => requireContext.keys().map(requireContext)
let req = require.context('./svg', false, /\.svg$/)
requireAll(req)

這樣經過 map 遍歷,結合引入上下文對象做爲回調函數,便可獲取引入某個目錄下的 svg 資源。對象

一個歸併方法:reduce

array.reduce(callback[, initialValue])第一個參數是每一項上調用的函數,該函數有四個參數:

  1. accumulator:累加回調返回值;他是上一次調用時返回的累積值,或initValue
  2. currentValue:數組中正在處理的元素;
  3. currentIndex:數組中正在處理的當前元素的索引。若是提供了initialValue,這索引號爲0,不然索引爲1;
  4. array:調用reduce()的數組。

當第二個參數省略時,遍歷從數組第二項開始,數組第一項被看成前一個值accumulator

數組求和

const numbers = [10, 20, 30, 40];
numbers.reduce((acc, cur, index, arr) => {
  console.log('acc: ' + acc + '; ' + 'cur: ' + cur + ';');
  return acc + cur;
})

結果爲:

acc: 10; cur: 20;
acc: 30; cur: 30;
acc: 60; cur: 40;

這第二個參數就是設置accumulator的初始類型和初始值,好比爲0,就表示accumulator的初始值爲Number類型,值爲0,所以,reduce的最終結果也會是Number類型。

const numbers = [10, 20, 30, 40];
numbers.reduce((acc, cur, index, arr) => {
  console.log('acc: ' + acc + '; ' + 'cur: ' + cur + ';');
  return acc + cur;
}, 0)

結果爲:

acc: 0; cur: 10;
acc: 10; cur: 20;
acc: 30; cur: 30;
acc: 60; cur: 40;

強大的reduce

reduce做爲歸併方法,在有些情形能夠替代其它數組操做方法,強大之處,還得要落實在具體的案例上。

假設如今有一個數列[10, 20, 30, 40, 50],每一項乘以2,而後篩選出大於60的項。

在這裏更新數組每一項(map的功能)而後篩選出一部分(filter的功能),若是是先使用map而後filter的話,你須要遍歷這個數組兩次。在這裏用reduce更高效。

var numbers = [10, 20, 30, 40, 50];
var result = numbers.reduce(function (acc, cur) {
  cur = cur * 2;
  if (cur > 60) {
    acc.push(cur);
  }
  return acc;
}, []);
console.log(result); // [80, 100]

從這個例子能夠看出reduce完成了mapfilter的使命。

統計數組中重複出現項的個數,用對象表示。
var letters = ['A', 'B', 'C', 'C', 'B', 'C', 'C'];
var letterObj = letters.reduce(function (acc, cur) {
  acc[cur] = acc[cur] ? ++acc[cur] : 1;
  return acc;
}, {});
console.log(letterObj); // {A: 1, B: 2, C: 4}
數組去重
var letters = ['A', 'B', 'C', 'C', 'B', 'C', 'C'];
var letterArr = letters.reduce(function (acc, cur) {
  if (acc.indexOf(cur) === -1) {
    acc.push(cur);
  }
  return acc;
}, []);
console.log(letterArr); //  ["A", "B", "C"]

ps:瞭解更多數組去重方法,點這裏

與ES6的結合

與ES6結合使用也會擦出很多火花。

刪除目標對象某個屬性。
const person = {
  name: 'jazz',
  gender: 'male',
  age: 24
};
const personUnknowAge = Object.keys(person).filter((key) => {
  return key !== 'age';
})
.map((key) => {
  return {
    [key]: person[key]
  }
})
.reduce((acc, cur) => {
  return {...acc, ...cur};
}, {});
console.log(personUnknowAge); // {name: "jazz", gender: "male"}

更簡潔的方案,利用ES6中函數參數解構:

const personUnknowAge = (({name, gender}) => ({name, gender}))(person);
console.log(personUnknowAge); // {name: "jazz", gender: "male"}

固然還有更簡單的方案,利用ES6中對象解構:

const person = {
  name: 'jazz',
  gender: 'male',
  age: 24
};
let { age, ...personUnknowAge } = person;
console.log(personUnknowAge); // {name: "jazz", gender: "male"}

結尾

數組操做的「妙用」遠不止這些,後面有空再研究補充吧,完~

相關文章
相關標籤/搜索