Javascript Array中的filter、map和reduce

dongfeiwww 9年前發布 | 9K 次閱讀 JavaScript開發 JavaScript

前幾天寫了篇文章科普了下Javascript中 Array.filter() 的妙用,后來無意間發現了 一篇好文章 ,一次性科普了三個API: filter 、 map 和 reduce ,生動形象,尤其是配圖,顯然是用了心思。下面是譯文:

最近,一直在為一個客戶做一個視覺化數據的項目,從服務端API拉取數據回來然后轉換出視覺效果,自然少不了大量的數據操作,為此我一再使用Javascript中的Array 三個API:filter、map 和 reduce 。

Map 、 Filter 和 Reduce 常常被用于對一個數組做一些操作,進而轉換成某個新的東西(數據類型不一定還是數組哦~)。下面是我對這三個API的直觀認識:

Map

你想將一個數組中的每一項做個轉換,結果生成了一個新數組,并且新數組的長度和原數組一致。

Filter

你想將一個數組做一個過濾,按照某規則提取出一些特定的項來。結果也生成了一個新數組,但新數組的長度小于或等于原數組。

Reduce

你想通過遍歷一個數組的每一項來計算出一個新東西,最后生成的結果可以是任何類型的變量:一個新數組,一個新對象,一個新布爾值…

filter 、 map 和 reduce 共同點就是并不會對原數組做任何改動,結果都是生成一個新變量。讓我們來看一些例子:

Array.map()

現在我們有一個對象列表,其中每個對象代表的是一種變形金剛(譯注:看來這位歪果仁是個變形金剛粉絲):

var transformers = [
  {
    name: 'Optimus Prime',
    form: 'Freightliner Truck',
    team: 'Autobot'
  },
  {
    name: 'Megatron',
    form: 'Gun',
    team: 'Decepticon'
  },
  {
    name: 'Bumblebee',
    form: 'VW Beetle',
    team: 'Autobot'
  },
  {
    name: 'Soundwave',
    form: 'Walkman',
    team: 'Decepticon'
  }
];

那么,問題來了,如果想得到一個包含所有變形(form)的列表該怎么做呢? Array.map() 讓一切變得簡單。它的基本使用語法是這樣的:

Array.prototype.map(callback(item));

當然,還有種更復雜點的語法場景,只不過不常用到:

Array.prototype.map(callback(item[, index], array])[, thisArg]);

callback 會遍歷數組的每個元素,在其中返回的每一個數值將會組成新數組。 callback 有多種書寫方式:

命名函數:

functiongetForm(transformer){
  return transformer.form;
}
var robotsInDisguise = transformers.map(getForm);
/** robosInDisguise === ['Freightliner Truck', 'Gun', 'VW Beetle', 'Walkman'] */

匿名函數:

robotsInDisguise = transformers.map(function(transformer){
  return transformer.form;
});

箭頭函數:

robotsInDisguise = transformers.map(transformer => transformer.form);

ES2015的箭頭函數和 Array.map() 搭配使用簡直不能更爽了!

Array.filter()

語法:

Array.prototype.filter(callback(item));

callback 將數組元素當參數傳入,并返回一個布爾值。當返回值為真時,該元素被加入新數組中,反之則被過濾掉。

現在我們把這些變形金剛過濾出 汽車人 (Autobots)

functionisAutobot(transformer){
  return transformer.team === ‘Autobot’;
}

var autobots = transformers.filter(isAutobot);
/**
autobots ==  [
  {
    name: 'Optimus Prime',
    form: 'Freightliner Truck',
    team: 'Autobot'
  },
  {
    name: 'Bumblebee',
    form: 'VW Beetle',
    team: 'Autobot'
  }
]
*/

Array.reduce()

Array.reduce() 是通過遍歷每個數組元素對其做運算,因此,也是三個API之間最富有技巧的,其使用語法也略顯復雜:

Array.prototype.reduce(callback(previousValue, currentValue[, index], array]), initialValue)

謹記一條:我們是將數組元素通過遍歷減少到一個值。比如現在有一組 可組合變形金剛 (譯者注:我也不知道什么鬼,該怎么翻譯,原詞:Construction Transformers),它們能夠組合成更大的變形金剛,我們可以通過代碼來做出這樣的組合:

var constructicons = [
  {
    name: 'Scrapper',
    form: 'Freightliner Truck',
    team: 'Decepticon',
    bodyPart: 'rightLeg'
  },
  {
    name: 'Hook',
    form: 'Mobile Crane',
    team: 'Decepticon',
    bodyPart: 'upperTorso'
  },
  {
    name: 'Bonecrusher',
    form: 'Bulldozer',
    team: 'Decepticon',
    bodyPart: 'leftArm'
  },
  {
    name: 'Scavenger',
    form: 'Excavator',
    team: 'Decepticon',
    bodyPart: 'rightArm'
  },
  {
    name: 'Mixmaster',
    form: 'Concrete Mixer',
    team: 'Decepticon',
    bodyPart: 'leftLeg'
  },
  {
    name: 'Long Haul',
    form: 'Dump Truck',
    team: 'Decepticon',
    bodyPart: 'lowerTorso'
  }
];

Reduce的 callback 需要至少兩個參數。第一個是從上次遍歷中返回的一個值,第二個是當前數組遍歷到的一個值,返回值又將當做第一個參數被傳入到下一次遍歷。

functionassemble(combiner, transformer){
  //每次遍歷都會將當前的變形金剛(transformer)的名字加入到組合器(combiner)的form中去。
  combiner.form[transformer.bodyPart] = transformer.name;
  return combiner;
}

這樣,我們可以在調用reduce的時候,將 assemble 當做第一個參數傳入,第二個參數是用來初次調用時的初始數據。接下來的例子便是我們提供一個僅僅有名字(name)和派別(team)的變形金剛,通過reduce中的 assemble 我們來組合成一個強大的變形金剛吧!

var devastator = constructicons.reduce(assemble, {
  name: ‘Devastator’,
  team: ‘Decepticon’,
  form: {}
});
/*
devastator == {
  name: ‘Devastator’,
  team: ‘Decepticon’,
  form: {
    leftArm: "Bonecrusher"
    leftLeg: "Mixmaster"
    lowerTorso: "Long Haul"
    rightArm: "Scavenger"
    rightLeg: "Scrapper"
    upperTorso: "Hook"
  }
}
*/

這些三個基本API一旦組合起來使用,也是很強大的。

來自:http://zerosoul.github.io/2016/12/06/array-filter-map-reduce-in-js/

 

 本文由用戶 dongfeiwww 自行上傳分享,僅供網友學習交流。所有權歸原作者,若您的權利被侵害,請聯系管理員。
 轉載本站原創文章,請注明出處,并保留原始鏈接、圖片水印。
 本站是一個以用戶分享為主的開源技術平臺,歡迎各類分享!