js數組操作常用方法及注意事項

參考文章:

1. forEach()的使用及注意事項

forEach的使用頻率很高,多用於對數組自身的改變和各元素相關統計性的計算,重要特性如下:

  • 可以改變數組自身,沒有返回值;
  • 中途不能用常規操作跳出循環,
  • 可以用拋出異常(try/catch)的方式,但不推薦這樣做。
  • 改變數組自身:當數組中元素是值類型,forEach不會改變數組元素;當是引用類型,則可以改變數組元素
var arr1 = [
   {name:'鳴人',age:16},
   {name:'佐助',age:17}
];
var arr2 = [1,2,3];

arr1.forEach(item => { 
  item.age = item.age + 1}
);

//=> [{name:'鳴人',age:17},{name:'佐助',age:18}]

arr2.forEach(item => {
  item = item * 2}
)

// => [1,2,3]

易錯點

  • 不支持鏈式操作,所以以下代碼是錯誤的:
[1,2,3,4,5].forEach(
   item => console.log(item)
).filter(item => { 
   return item > 2 
})
// Uncaught TypeError: Cannot read property 'filter' of undefined
  • 注意這裏我們說僅僅是forEach()這個方法不支持鏈式調用,在調用forEach之前,前面的數組你怎麼玩鏈式都沒問題,最後返回一個正常數組即可:

// 這個沒問題
[1,2,3,4,5].filter(item => { 
  return item > 2 
}).forEach(item => {
   console.log(item) 
})

2. map()的使用及注意事項

map()功能很強大,forEach()的一些侷限性它很多都能解決。"map"即"映射",也就是原數組被"映射"成對應新數組。

  • 該數組中的每個元素都調用一個提供的函數後返回結果。
  • 建一個數組,需要有承載對象,也意味着原始數組在調用它後不會發生變化,但這不代表不能用它改變原數組,用原有數組去承載就可實現改變原數組
let arr = [1,2,3];
arr = arr.map(item => { return item * 2 })
  • map()中每個元素都要執行相應的回調函數,所以必須要有return(千萬別學某些人,判斷過程一複雜,忘了return,最後得到的是個空數組,哭天喊地的~~~),如果你想給數組做一定的過濾處理,那map()基本上行不通:
let newArr = [1,2,3,4,5].map(item => { if(item > 3) return item })
// => [undefined, undefined, undefined, 4, 5]

3. filter()的使用

衆所周知,map()沒法做到的過濾,就交給filter()去完成。filter()和map()很像,也是創建一個新數組,新數組中的元素是篩選出來的符合條件的所有對象。使用如下:

let newArr = [1,2,3,4,5].filter(item =>{
   if(item > 3) return item 
})
//  => [4,5]

4. sort()的使用

sort()用於對數組的元素進行排序。排序順序可以是字母或數字,並按升序或降序。使用如下:

[3,4,2,1,5].sort()
// => [1,2,3,4,5]

['Javascript','Vue','React','Node','Webpack'].sort();
// => ["Javascript", "Node", "React", "Vue", "Webpack"]
  • sort()與map()、filter()等不同,它直接改變原始數組
  • 如果想按照其他標準進行排序,就需提供比較函數compareFunction(a,b),數組會按照調用該函數的返回值排序,即a和b是兩個將要比較的元素
    • 如果compareFunction(a,b)小於0,則a排列到b之前;
    • 如果 compareFunction(a, b)等於0,a和b的相對位置不變(並不保證);
    • 如果 compareFunction(a, b)大於0,b排列到a之前
let Users = [
  {name:'鳴人',age:16},
  {name:'卡卡西',age:28},
  {name:'自來也',age:50},
  {name:'佐助',age:17}
];
Users.sort((a,b)=> {
   return a.age - b.age
})

// => 鳴人、佐助、卡卡西、自來也

5. some()的使用

some()也是很好的一個方法,用於檢查數組中是否有某些符合條件的元素。只要有一個滿足即返回true,之後的不再執行,對性能很友好。

var result = [
   {name:'鳴人',age:16},
   {name:'佐助',age:17}
].some(item => {
    return item.age > 16 
});
=> true

6. every()的使用

如果說some()是 ||判斷,那every()就是&&判斷,它用於檢測數組中的每一項是否都滿足條件,只有都滿足了纔會返回true。

var result = [
   {name:'鳴人',age:16},
   {name:'佐助',age:17}
].every(item => {
    return item.age > 16 
});
=> false

 

7. 其他經典處理方法

(1) 數組去重

  • 數組元素是值類型:可用new Set()去重(注意:new Set()會將結果轉換成對象)
let tempArr = new Set([1,2,3,3,4,4,5])
// => {1,2,3,4,5} 

//並且已有元素是添加不進去的:
tempArr.add(3) 
// => {1,2,3,4,5}

tempArr.add(6)
// => {1,2,3,4,5,6}

  • 數組元素是引用類型:Set()無法對 元素是引用對象的數組 進行去重
let mySet = new Set();
mySet.add(1); // Set(1) {1}
mySet.add(5); // Set(2) {1, 5}
mySet.add(5); // Set(2) {1, 5} 這裏體現了值的唯一性
mySet.add('some text'); 
[...mySet]
// => [1,5,'some text']

mySet.add({name:'jay Chou',age:40});
mySet.add({name:'jay Chou',age:40});

[...mySet]
// => [1,5,'some text',{name:'jay Chou',age:40},{name:'jay Chou',age:40}]

  • .uniqWith():Lodash是一個一致性、模塊化、高性能的JavaScript實用工具庫。它提供了一個很好的方法——.uniqWith()
import _ from 'lodash';
<script>
var objects = [{ 'x': 1, 'y': 2 }, { 'x': 2, 'y': 1 }, { 'x': 1, 'y': 2 }];
_.uniqWith(objects, _.isEqual);
</script>

//=> [{ 'x': 1, 'y': 2 }, { 'x': 2, 'y': 1 }]

其中, _.isEqual(value,other)用於執行深比較來確定兩者的值是否相等。 _.uniqWith()做去重處理。

(2) 查找指定元素:判定當前數組裏是否有某個元素,若有則獲取該元素

當需要在數組中找到指定的元素並返回給我們時:some()只會告訴我們該元素是否存在; 使用filter()可以實現該需求;但如果我們已經知道這個數組裏有且僅有一個我們想要的元素,出於性能的考慮,並不想用filter()從頭遍歷到尾(filter不支持中斷遍歷),此時可使用如下方法來實現。

  • 使用 findIndex():若有該元素則返回第一次出現在數組中的的索引值,若沒有該元素則返回-1
let testArr = [{name:'鳴人',age:16},{name:'佐助',age:17},{name:'卡卡西',age:26}]
let index = testArr.findIndex(item => { return item.age > 16 });
// => 1
  • 或者也可以使用Lodash提供的_.findIndex(),通過對象屬性值直接獲取對應索引
let testArr = [{name:'鳴人',age:16},{name:'佐助',age:17},{name:'卡卡西',age:26}]
let index = _.findIndex(testArr, {name:'佐助'});
// => 1

 

  • 使用 find():在數組中找到我們所需要的元素,並且和some()一樣,只要有一個滿足即返回該元素,不會多餘遍歷,對性能很友善。
let testArr = [{name:'鳴人',age:16},{name:'佐助',age:17},{name:'卡卡西',age:27},{name:'佐助',age:17}]
let result = testArr.find(item => { return item.name == '佐助'});
// => { name:'佐助',age:17 }

 

(3) 刪除指定元素:判定當前數組裏是否有某個元素,若有則把它刪除

let testArr = [{name:'鳴人',age:16},{name:'佐助',age:17},{name:'卡卡西',age:27},{name:'佐助',age:17}]
let index= testArr.findIndex(item => { return item.name == '佐助'});
// => 1

testArr.splice(index,1)
=> [{name:'鳴人',age:16},{name:'卡卡西',age:27},{name:'佐助',age:17}]

8. 其他彙總

  • 計算數值型數組中元素的最大(小)值
var arr = [1,3,4,5,8,4];
var max = Math.max.apply(null, arr);
console.log(max);  //=> 8

var min = Math.min.apply(null, arr);
console.log(min);  //=> 1

  • 計算數值型數組中各元素之和

a. 普通方法

var arr = [1,3,4,5,8,4];
var result = 0
for(var i=0;i<arr.length;i++){
  result = result + arr[i]
}
console.log(result);  //=> 25

b. 優化:和普通算法(遍歷)相比,下面的算法時間複雜度會降低很多,並且數據量越大越有優勢

var arr = [1,3,4,5,8,4];
var sum = eval(arr.join("+"));
console.log(sum);  //=> 25

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章