摘要:總結遍歷數組的時候應該盡量使用這些,靈活運用可以讓代碼更加優雅,這種盡可能使用函數和鏈式調用的風格很接近函數式編程,可以提高代碼質量。
js中有很多可以遍歷數組的API,既然已經封裝的這么好,為什么不在平常開發的時候使用,本文講講forEach、map、filter、some、every、reduce這些API的使用,并且和普通的for語句作對比。
我們以一個對象數組作為測試數據:
const testArr = [ { id: 1, name: "張三", age: 18 }, { id: 2, name: "李四", age: 24 }, { id: 3, name: "王小二", age: 22 } ];forEach
打印出所有對象的id,for語句寫法如下:
for (let i = 0, len = testArr.length; i < len; i++) { console.log(testArr[i].id); // 1, 2, 3 }
簡單易懂,接下來看看forEach的寫法:
testArr.forEach(item => console.log(item.id)); // 1, 2, 3
兩者結果是一樣的,for語句是命令式編程風格,而forEach是聲明式編程風格;前者會告訴機器該如何做,而后者只關注要做什么。我們推崇后一種寫法,應該盡量使用forEach,這樣我們還不需要寫for()里面一大串的表達式,何樂而不為。(ps:如果對性能吹毛求疵的話,還是老老實實用for吧!)
map現在我們想得到所有對象的name并組成新的數組,for語句寫法如下:
let names = []; for (let i = 0, len = testArr.length; i < len; i++) { names.push(testArr[i].name); } console.log(names); // [ "張三", "李四", "王小二" ]
比較啰嗦,這種對原數組每個元素進行指定操作并最后返回新數組的問題用map再合適不過了:
testArr.map(item => item.name); // [ "張三", "李四", "王小二" ]
對比for語句,map是多么優雅啊!
關于map,有個需要注意的點:
[1, 2, 3].map(parseInt); // [ 1, NaN, NaN ]
這里有些同學會有些疑惑,為什么結果不是[1, 2, 3]呢?
其實很簡單,map會將三個參數(當前正在遍歷的元素,當前元素索引,原數組本身)傳給parseInt,而parseInt是可以有兩個參數的。
這時候就相當于執行以下代碼:
parseInt(1, 0); // 1 parseInt(2, 1); // NaN parseInt(3, 2); // NaN
所以結果為[1, NaN, NaN],而不是[1, 2, 3]。
filter有時候我們需要篩選出符合指定條件的元素,比如age大于18的對象,for的寫法如下:
let newArr = []; for (let i = 0, len = testArr.length; i < len; i++) { if (testArr[i].age > 18) { newArr.push(testArr[i]); } } console.log(newArr); // [ { id: 2, name: "李四", age: 24 }, { id: 3, name: "王小二", age: 22 } ]
可以看到,寫法很啰嗦,此時用filter的話就很方便了:
testArr.filter(item => item.age > 18); // [ { id: 2, name: "李四", age: 24 }, { id: 3, name: "王小二", age: 22 } ]
filter還可以用于數組去重,代碼如下:
const arr2 = [1, 2, 4, 1, 3, 2, 6]; arr2.filter((item, idx, arr) => { return arr.indexOf(item) === idx; }); // [ 1, 2, 4, 3, 6 ]map + filter
獲取所有對象的某種屬性,事先需要判斷對象是否具有該屬性,for寫起來有點丑陋:
function getAllOfSomeProps (array, props) { let arr = []; array.forEach((item) => { if (item[props]) { arr.push(item[props]); // => item[props] && arr.push(item[props]) } }) return arr; } getAllOfSomeProps(testArr, "sex"); // [] getAllOfSomeProps(testArr, "id"); // [ 1, 2, 3 ] getAllOfSomeProps(testArr, "name"); // [ "張三", "李四", "王小二" ]
map + filter的組合就優雅的多了:
return array.map(item => item[props]).filter(item => item);
我們再舉個比較通俗的例子,比如我們需要獲得數組里所有age大于18的對象的name,for語句如下:
let newNames = []; for (let i = 0, len = testArr.length; i < len; i++) { if (testArr[i].age > 18) { newNames.push(testArr[i].name); } } console.log(newNames); // [ "李四", "王小二" ]
再看看 map + filter 的寫法:
testArr.filter(item => item.age > 18).map(item => item.name); // [ "李四", "王小二" ]
還是很優雅。
some有時候我們需要添加新對象但是某些屬性不能重復,for的寫法如下:
function isRepeat (array, props, value) { for (let i = 0, len = array.length; i < len; i++) { if (array[i][props] === value) { return true; } } return false; }
some方法測試數組中的某些元素是否通過指定函數的測試,改寫如下:
function isRepeat (array, props, value) { return array.some(item => item[props] === value); } isRepeat(testArr, "name", "張三"); // true isRepeat(testArr, "name", "李白"); // falseevery
我們需要檢測某個數組里的每個對象是否都具有某種屬性,for的寫法如下:
function hasSomeProps (array, props) { for (let i = 0, len = array.length; i < len; i++) { if (!array[i][props]) { return false; } } return true; }
every方法測試數組的所有元素是否都通過了指定函數的測試。改寫如下:
function hasSomeProps (array, props) { return array.every(item => item[props]); } hasSomeProps(testArr, "name"); // true跳出循環
有時需要在滿足某條件下終止循環,比如打印對象信息,直到name為李四:
for使用break:
for (let i = 0, len = testArr.length; i < len; i++) { if (testArr[i].name === "李四") { break; } console.log(testArr[i]); // { id: 1, name: "張三", age: 18 } }
some,當條件為真時返回true跳出循環:
testArr.some((item) => { if (item.name === "李四") { return true; } console.log(item); // { id: 1, name: "張三", age: 18 } })
every,當條件為真時返回false跳出循環:
testArr.every((item) => { if (item.name === "李四") { return false; } console.log(item); // { id: 1, name: "張三", age: 18 } })
因為forEach是沒有break的,這里我們可以使用some,every替代。
reduce計算[343, 34, 232, 4, 343, 335, 353535]的總和,for的寫法如下:
const arr = [343, 34, 232, 4, 343, 335, 353535]; let sum = 0; for (let i = 0, len = arr.length; i < len; i++) { sum += arr[i]; } console.log(sum); // 354826
使用reduce來做這種累加操作很方便:
arr.reduce((prev, curr) => prev + curr) // 354826
其實用法遠不止如此,同學們在平常學習或者工作中可以慢慢積累。
總結:遍歷數組的時候應該盡量使用這些API,靈活運用可以讓代碼更加優雅,這種盡可能使用函數和鏈式調用的風格很接近函數式編程,可以提高代碼質量。
文章版權歸作者所有,未經允許請勿轉載,若此文章存在違規行為,您可以聯系管理員刪除。
轉載請注明本文地址:http://specialneedsforspecialkids.com/yun/92842.html
摘要:結合工作中使用情況,簡單對進行一些復習總結,包括常用的語法,等,以及短時間內要上手需要重點學習的知識點不同工作環境可能有一些差別,主要參考鏈接是阮一峰的博客以及外文博客阮老師大部分文章是直接翻譯的這個博客簡介先說一下,是一個標準化組織,他們 結合工作中使用情況,簡單對es6進行一些復習總結,包括常用的語法,api等,以及短時間內要上手需要重點學習的知識點(不同工作環境可能有一些差別),...
摘要:基礎布局的中主要為部分,分別是用于搜索篩選和分頁的表單控件用于排序表格的表頭以及用于展示數據的。這也是前瞻發布之后,提出廢棄部分功能后許多人反應較為強烈的原因。 與上周的第一篇實踐教程一樣,在這篇文章中,我將繼續從一種常見的功能——表格入手,展示Vue.js中的一些優雅特性。同時也將對filter功能與computed屬性進行對比,說明各自的適用場景,也為vue2.0版本中即將刪除的部...
摘要:基礎布局的中主要為部分,分別是用于搜索篩選和分頁的表單控件用于排序表格的表頭以及用于展示數據的。這也是前瞻發布之后,提出廢棄部分功能后許多人反應較為強烈的原因。 與上周的第一篇實踐教程一樣,在這篇文章中,我將繼續從一種常見的功能——表格入手,展示Vue.js中的一些優雅特性。同時也將對filter功能與computed屬性進行對比,說明各自的適用場景,也為vue2.0版本中即將刪除的部...
摘要:接口也是集合中的一員,但它與接口有所不同,接口與接口主要用于存儲元素,而主要用于迭代訪問即遍歷中的元素,因此對象也被稱為迭代器。迭代器的實現原理我們在之前案例已經完成了遍歷集合的整個過程。 【Collection、泛型】 主要內容 Collection集合 迭代器 增強for 泛型 教學目標 [ ] 能夠說出集合與數組的區別 [ ] 說出Collection集合的常用功能 [ ]...
摘要:走近可以膚淺地理解成為靈活的數組,我們在定義數組的時候,是要確定數組的大小的。在內部,向量使用一個動態分配的數組來存儲它們的元素。當插入新元素時,為了增加數組的大小,可能需要重新分配數組,這意味著分配一個新數組并將所有元素移動到該數組中。 ...
閱讀 3513·2021-11-17 17:01
閱讀 3918·2021-11-08 13:12
閱讀 2477·2021-10-08 10:04
閱讀 687·2021-09-29 09:35
閱讀 1418·2021-09-26 10:12
閱讀 2020·2021-09-07 09:58
閱讀 1953·2019-08-30 15:55
閱讀 2134·2019-08-30 13:14