Array是資料結構的一種,概念就像置物櫃一樣,每個櫃子都可以存放資料並且都有自己的編號稱為索引值index,Array為連續的記憶體位置,因此讀取資料非常快速,只要透過 array[index]就可以拿到資料了,時間複雜度為O(1),不過如果需要新增或刪除資料,就會有牽一髮動全身的問題,假如刪除了陣列的第一個資料,則後續的資料都需要向前遞補,時間複雜度為O(n),n為陣列的長度,以下就來介紹陣列常用的方法。
array的索引值是從0開始
let arr = []
//在建立陣列時就先賦值
let memberList = ['Tom', 'Jack', 'Alice'];
取得特定位置的值
memberList[0]; //'Tom'
獲取陣列的長度
memberList.length; //3
移除陣列最後一個值,並回傳移除的項目
memberList.pop(); // 'Alice'
在陣列的最後面新增一個值
memberList.push("Rose");
移除陣列的第一個值,並回傳移除的項目
memberList.shift();
在陣列的最前面新增一個值
memberList.unshift("Shane");
尋找目標對象在陣列中的索引值,如果找不到的話就會回傳-1
memberList.indexOf("Jack"); //1
取指定對象最後一個出現的索引值,如果找不到的話就會回傳-1
let student = ['Tom', 'Marry', 'Waston', 'Tom']
let lastPosition = student.lastIndexOf('Tom')
console.log(lastPosition) // 3
檢查該陣列是否有這個值,有的話回傳true,沒有的話回傳false
memberList.includes("Jack"); //true
尋找目標對象在陣列中的索引值,如果找不到的話就會回傳-1
let student = [{id:1, name:'Tom'},{id:2, name:'Marry'},{id:3, name:'Waston'},{id:4, name:'Tina'}]
let res = student.findIndex((item) => {
return item.name == 'Marry'
})
console.log(res) //1
用來切割陣列,不會改變原陣列
let memberList = ['Tom', 'Jack', 'Alice', 'Zora', 'Mike'];
memberList.slice(0, 2); //["Tom", "Jack"]
console.log(memberList) //['Tom', 'Jack', 'Alice', 'Zora', 'Mike'];
//如果想要用slice做淺拷貝可以這樣寫
memberList.slice()
用來切割陣列,會回傳切除的部位,當陣列經過splice的處理之後,原陣列也會跟著改變
let memberList = ['Tom', 'Jack', 'Alice', 'Zora', 'Mike'];
memberList.splice(0, 2) //["Tom", "Jack"] //回傳被切割出來的陣列
console.log(memberList) //["Alice", "Zora", "Mike"] // 原陣列被修改了
//帶入第三個參數addItem
let memberList = ['Tom', 'Jack', 'Alice', 'Zora', 'Mike'];
memberList.splice(0, 2, 'Dan') //["Tom", "Jack"] //回傳被切割出來的陣列
console.log(memberList) //["Dan", "Alice", "Zora", "Mike"]
遍歷陣列除了傳統的for迴圈之外,也可以使用forEach或是for of
//forEach
memberList.forEach((item, index, array) => {
console.log(`name${item}`, `index${index}`);
});
//for of
for (let value of memberList) {
console.log("name", value);
}
類似工廠的概念,陣列的元素會被逐一加工,最後會回傳一個處理過後陣列
let student = ['Tom', 'Marry', 'Waston', 'Petter']
let result = student.map(item => {
return `**${item}**`
})
console.log(result) //['**Tom**', '**Marry**', '**Waston**', '**Petter**']
過濾符合條件想要篩選出來的對象,若沒有則回傳空陣列
let family =['Tom','Marry','Waston','Petter']
let res = family.filter(item => {
return item.includes('o')//搜尋誰的名字裡含有"o"的
})
console.log(res) //['Tom', 'Waston']
面試很喜歡問find跟filter的差異,filter會回傳一個陣列包含所有符合條件的對象,find則是只能回傳第一個符合條件的對象,沒有的話則return undefined
let family =['Tom','Marry','Waston','Petter']
let res = family.find(item => {
return item.includes('o')//搜尋誰的名字裡含有"o"的
})
console.log(res) //'Tom' 只回傳第一個找到的
檢查陣列的每一個項目是否符合條件,只要有一個對象不符合就return false
let list = ['tea','soda','water']
let res = list.every(item => {
return item.length == 3 //是否每個項目的長度都大於3
})
console.log(res) //false
陣列中只要有一個對象符合條件,就return true
let list = ['tea','soda','water']
let res = list.some(item => {
return item.length >= 5 //是否項目的長度大於5
})
console.log(res) //true
將陣列由小到大排序,字母的話按照a-z,如果沒有帶入callback function,就會將陣列每個項目轉換成字串來比對,不過這裡就會發現一個問題,為甚麼300會排在55的前面?因為以比對字串來說,300的「3」小於55的「5」,因此才會出現300比55還小的這種詭異情形。
let family =['Tom','Marry','Waston','Petter']
family.sort() //['Marry', 'Tom', 'Tom', 'Waston']
let num = [12,25,55,300]
num.sort() //[12, 25, 300, 55]
num.sort((prev, next) => next - prev);
console.log(num); //[300, 55, 25, 12] 由大到小排列
num.sort((prev, next) => prev - next);
console.log(num); //[12, 25, 55, 300] 由小到大排列
反轉陣列的順序
let member = ['Tom','Marry','Waston','Petter']
let res = member.reverse()
console.log(res) //['Petter', 'Waston', 'Marry', 'Tom']
將多個陣列串聯成同一個陣列
let teamA = ['Tom','Marry','Waston','Petter']
let teamB = ['Kevin','Joe','Vicky','Roy']
let teamAll = teamA.concat(teamB)
console.log(teamAll)
//["Tom", "Marry", "Waston", "Petter", "Kevin", "Joe", "Vicky", "Roy"]
將陣列的元素傳入callback處理,最後陣列會化作單一值(引用MDN的說明)array.reduce(callback(accumulator, currentValue, currentIndex, arr), initialValue)
let array = [1, 2, 3, 4];
let reducer = (accumulator, currentValue) => accumulator + currentValue;// 1 + 2 + 3 + 4
console.log(array.reduce(reducer));
// expected output: 10 // 5 + 1 + 2 + 3 + 4
console.log(array.reduce(reducer, 5));
// expected output: 15
因此用reduce來找陣列裡面最大或是最小的數字也是很方便的
let array = [1, 2, 3, 4];
let res = array.reduce((accumulator, currentValue)=>{
return Math.max(accumulator, currentValue)
})
console.log(res)
//output: 5
跟reduce差不多,不過順序變成由右至左,如果是做數字加總那結果是一樣的,如果是組字串那就可以看得出差異
let array = ['a', 'b', 'c', 'd', 'e'];
let left = array.reduce((prev, cur)=>{ return prev + cur; });
let right = array.reduceRight((prev, cur)=> { return prev + cur; });
console.log(left); // "abcde"
console.log(right); // "edcba"
可以將類陣列轉換成陣列Array.from(arrayLike, mapFn , this)
Array.from('Hello')
//output: ['H','e','l','l','o']
假如今天我想要建立一個數字1–99的陣列可以怎麼做?一個一個慢慢寫當然是可以,只是寫完可能就天黑了,使用Array from搭配map一行輕鬆搞定。
Array.from({length: 99}, (v, i) => i+1)
函數以遞迴方式將特定深度的子陣列重新串接成為一新的陣列,會傳入參數來指定巢狀陣列展開的深度,沒有傳的話預設是1。
let arr1 = [1, 2, [3, 4]];
arr1.flat(); // [1, 2, 3, 4]
let arr2 = [1, 2, [3, 4, [5, 6]]];
arr2.flat(); // [1, 2, 3, 4, [5, 6]]
let arr3 = [1, 2, [3, 4, [5, 6]]];
arr3.flat(2); // [1, 2, 3, 4, 5, 6]
將陣列裡的項目組成字串,可指定間隔字串
let family =['Tom','Marry','Waston','Petter']
let str = family.join('!')
console.log(str) //"Tom!Marry!Waston!Petter"
填滿的概念,把大家通通變成指定的元素,會改變原本的陣列
let student = ['Tom','Marry','Waston','Tom']
var res = student.fill('shane')
console.log(res)
//['shane', 'shane', 'shane', 'shane']
最後放上Tommy大大繪製的陣列操作大全,最常用陣列操作方法都列在上面了!
*圖片來源:*https://github.com/tooto1985/js-array-operations