趕忙閱讀讀此文,我保證,在過去的幾個月裏我,我肯定我在數組問題上犯過4次錯誤。因而我寫下這篇文章,閱讀這篇文章可讓你更準確的使用javascript數組的一些方法javascript
「若是你在數組中搜索某個元素,那麼請使用Array.indexOf」 ,我記得在學習javascript時看到過這個句子,毫無疑問,這句話很對。java
MDN文檔上這樣描述 rray.indexOf「返回第一個被搜索到的元素的下標(索引)」 ,因此若是你想要搜索某個元素的下標,那麼Array.indexOf能夠很好的解決。數組
可是,若是咱們想查看一個數組中是否包涵某個元素該如何作呢。就像yes/no這樣的問題,也就是布爾值。這裏咱們推薦使用返回布爾值的Array.includes方法。bash
const persons = ["jay","leinov","jj","nico"];
console.log(persons.indexOf("leinov"));
// 1
console.log(persons.indexOf("beyond"));
// -1
console.log(persons.includes("leinov"));
// true
console.log(persons.includes("beyond"));
// false
複製代碼
Array.filter是一個很是有用的方法,它經過一個數組的回調參數建立一個新的數組,正如他的名字所示,咱們使用它過濾出一個更短的數組函數
可是 若是咱們明確的知道回調函數返回的只是數組中的一項,這樣的話我不推薦使用他,例如,當使用的回調參數過濾的是一個惟一的id,這種狀況,Array.filter返回一個新的包涵這一項的數組。尋找一個特殊的id,咱們目的只想取一項出來,這個返回的數組就是無用的。性能
接下來咱們看下性能,爲了返回可以匹配回調函數的每一項,Array.filter必須檢索整個數組,此外讓咱們想象下,咱們有數百個項知足咱們的回調參數函數,咱們過濾的數組就很是大了。學習
爲了不這種狀況,我推薦Array.find ,他同Array.filter同樣須要一個回調函數參數,而且返回第一個可以知足回調函數參數的那一項。而且Array.find 在知足篩選後中止篩選,不會檢索整個數組。ui
use strict'; const singers = [ { id: 1, name: '周杰倫' }, { id: 2, name: '李建' }, { id: 3, name: '庾澄慶' }, { id: 4, name: '謝霆鋒' }, { id: 5, name: '周杰倫' }, ]; function getSinger(name) { return signer => signer.name === name; } console.log(singers.filter(getSinger('周杰倫'))); // [ // { id: 1, name: '周杰倫' }, // { id: 5, name: '周杰倫' }, // ] console.log(characters.find(getSinger('周杰倫'))); // { id: 1, name: '周杰倫' } 複製代碼
我認可常常在這上面犯錯,而後,個人一個好朋友提醒我看下MDN文檔去尋找一個更好的方式解決,這點跟上面的Array.indexOf/Array.includes很類似spa
在前面提到 Array.find 須要一個回調函數做爲參數來返回一個知足的元素。若是咱們須要知道數組是否包涵某個值時,Array.find是最好的方式嗎。或許不是,由於返回的是一個值,不是一個布爾值。翻譯
在這種狀況下,我推薦使用Array.some,它返回的是一個是否知足回調參數的布爾值
'use strict';
const characters = [
{ id: 1, name: 'ironman', env: 'marvel' },
{ id: 2, name: 'black_widow', env: 'marvel' },
{ id: 3, name: 'wonder_woman', env: 'dc_comics' },
];
function hasCharacterFrom(env) {
return character => character.env === env;
}
console.log(characters.find(hasCharacterFrom('marvel')));
// { id: 1, name: 'ironman', env: 'marvel' }
console.log(characters.some(hasCharacterFrom('marvel')));
// true
複製代碼
讓咱們來看看Array.reduce,Array.reduce並不太好理解,可是若是咱們執行Array.filter,Array.map感受咱們好像錯過了什麼。
個人意思是,咱們檢索了數組兩次,第一次過濾和建立了一個短的數組,第二次建立了一個新的包涵咱們過濾獲取到的數組。爲了獲取結果咱們使用了兩個數組方法,每一個方法都有一個回調函數和一個數組,其中一個Array.filter建立的咱們以後是用不到的。
爲了不這個性能的問題,我建議使用Array.reduce來代替。相同的結果,更好的代碼。Aaray.reduce允你篩選和添加知足的項目到累加器中。例如,這個累加器能夠是一個數字增量,一個要填充的對象,一個字符串或一個數組。
在咱們以前的例子中,咱們一直在使用Array.map,因此我建議使用Array.reduce來使用累加器來鏈接數組。在下面的示例中,根據env的值,咱們將將其添加到累加器中,或者將此累加器保留爲原來的值。
'use strict';
const characters = [
{ name: 'ironman', env: 'marvel' },
{ name: 'black_widow', env: 'marvel' },
{ name: 'wonder_woman', env: 'dc_comics' },
];
console.log(
characters
.filter(character => character.env === 'marvel')
.map(character => Object.assign({}, character, { alsoSeenIn: ['Avengers'] }))
);
// [
// { name: 'ironman', env: 'marvel', alsoSeenIn: ['Avengers'] },
// { name: 'black_widow', env: 'marvel', alsoSeenIn: ['Avengers'] }
// ]
console.log(
characters
.reduce((acc, character) => {
return character.env === 'marvel'
? acc.concat(Object.assign({}, character, { alsoSeenIn: ['Avengers'] }))
: acc;
}, [])
)
// [
// { name: 'ironman', env: 'marvel', alsoSeenIn: ['Avengers'] },
// { name: 'black_widow', env: 'marvel', alsoSeenIn: ['Avengers'] }
// ]
複製代碼
若有哪裏翻譯錯誤請指正 3Q