[JavaScript] Array與Object運算大全

JavaScript
Array
Object

Array篇

array與array合併

concat():const arr3 = arr1.concat(arr2)

concat()不會改變現有陣列(arr1、arr2),合併arr1、arr2後回傳新的陣列給const arr3

concat()的合併不做排序或是重複值刪除,就只是單純把arr2加到arr1後面


push():arr1.push(variable)

push()將變數加入arr1的末端,會改變arr1,注意push()是有return的,回傳的是新陣列長度,不是new arr1

如果要加入多個變數,方法有兩種

一是逗號分隔多個欲添加的variable:arr1.push(var1, var2, var3)

二是使用apply():Array.prototype.push.apply(arr1, arr2);

註:由於push()會改變原先的arr1,不能用在React系統中對於state的操作


Spread Operator:const arr3 = [...arr1, ...arr2]

JavaScript ES6的超級好用功能「Spread Operator」,直接新建const arr3



array開頭加東西

unshift():arr1.unshift(newItem1, newItem2, ...)

unshift()會將參數加入arr1開頭,new item不限制是哪種型別(Number、String、Object、Array...等都可以)

會改變arr1並回傳值,回傳的是新陣列的長度



array自己合併

join():arr1.join()、arr1.join(seperator)

join()通常用在想把array內的字串合併,seperator不填的話,所有字串會以逗號串接

不會改變arr1,但會回傳一個串接/合併全部items的字串


reduce():const value = arr1.reduce(callback_function[ accumulator, currentValue, currentIndex, array ], initialValue)

reduce()在陣列處理上相對少見,用於「縮減」陣列成一個項目/值。

第一個參數為callback_function,第二個參數為累加項目(accumulator)的初始值initivalValue (Optional)

如果有給initialValue,則accumulator初始值 = initialValuecurrentValue初始值 = arr1[0]

如果沒給initialValue,則accumulator初始值 = arr1[0],currentValue初始值 = arr1[1]

也就是說,有提供initialValue的話,reduce()會從陣列索引0開始跑callback_function;沒提供則是從陣列索引1開始跑。

callback_function的參數重要的就是前兩項(accumulatorcurrentValue),

currentIndex選填,有要拿當前index運算的就填進去

第四個參數 array ,指的就是arr1(執行reduce()的那個陣列),運算上有需要call就填進去

callback_function運算完記得return值,這個值會傳給下一輪作為更新後的accumulator

全部遍歷完後,reduce()回傳最終的accumulator,注意accumulator沒有限定一定要是Array,也可以是其他型別



移除array內的item

pop():const deletedItem = arr1.pop()

pop()相反於push(),移除arr1的最後一個item,會改變arr1,且回傳的是被刪掉的item,不是new arr1


shift():const deletedItem = arr1.shift()

shift()跟pop()很像,指是它移除的是arr1第一個item,會改變arr1,且回傳的是被刪掉的item,不是new arr1


splice():arr1.splice(start_index, delete_count, inserted_items)

splice()改變原陣列arr1,抽換items。從start_index後,刪除n個items(n = delete_count),刪除後插入inserted_items

delete_count選填,沒填的話就是不刪除既有items,直接插入

inserted_items選填,如果有delete_count而沒有inserted_items的話,就是單純刪除array items的用法

回傳的是被刪除的items陣列,沒有delete_count的話,回傳空陣列



array擷取

slice():const arr2 = arr1.slice(begin_index, end_but_not_include_index)

slice()包含自begin_index切出arr1給定的index範圍內物件,沒給第二個參數就是切到整個尾端

有給就是切到end_but_not_include_index前一個index

slice()不會改變arr1,會回傳一個新的array給arr2

不加任何params可用array複製:const arr1Copy = arr1.slice()


array遍歷

forEach():arr1.forEach((item) => { do something in callback function })

forEach()會遍歷每個item,執行callback function,不能在迴圈內寫continue、break、return,不會改變arr1,回傳值為undefined


map():const arr2 = arr1.map((item) => { do something in callback function})

map()跟上面的forEach很像,都是遍歷每個array內item執行callback function,不會改變arr1

不同點在於,會回傳item經callback function運算後的新陣列


for...of...:for (const item of arr1){ do something }

for...of...是ES6新功能,遍歷的對象為值(value)而不是key(index)

就是新的超好用的for迴圈,迴圈內可做continue、break、return等操作,不改變原始的arr1


filter():const arr2 = arr1.filter( (item) => { do something and then return true or false } )

filter()遍歷arr1內的各個item,依據callback function所回傳的true/false結果,若為true,則加入新的陣列

最後全部遍歷完,過濾出結果為true的items給arr2。filter()不會改變arr1

此乃超級常用的Array method!!!



array排序問題

reverse():const reversed_arr1 = arr1.reverse()

reverse()會將arr1的items反序,會改變arr1並回傳改變後的arr1

注意一件事,reverse()並沒有創造新的Array,reversed_arr1與arr1會是相同的reference

比如下列程式碼

var a = [1, 2, 3, 4];
const b = a.reverse();
console.log(a);
console.log(b === a);

//output
[ 4, 3, 2, 1 ]
true


sort():const sorted_arr1 = arr1.sort( compare_function )

sort()根據給定的compare_function來排序arr1 items,跟reverse()一樣,會改變arr1、回傳值為排序後的arr1,但是沒有創造新的Array,sorted_arr1與arr1會是相同的reference

var a = [5, 2, 3, 4];
const b = a.sort((a,b)=>a-b);
console.log(a);
console.log(b === a);

//output
[ 2, 3, 4, 5 ]
true


compare_function回傳值有 -1、0、1三種,這裡引用MDN說明如下

function compare(a, b) {
 if (在某排序標準下 a 小於 b) {
  return -1;
 }
 if (在某排序標準下 a 大於 b) {
  return 1;
 }
 // a 必須等於 b
 return 0;
}

//如果是一般的數字大小比較,可寫成下面的形式
function compareNumbers(a, b) {
  return a - b;
}

sort()在前端的Array運算內超常用到,比如資料展示或資料前處理。必學!!!



Object篇

Object相較於Array沒有那麼多複雜的原生JavaScript function可用,因為物件「key-value」特性,讓操作、運算上簡單很多。注意不論是Array還是Object,都是call by reference的,在複製上須小心。


object與object合併

Spread Operator:const obj3 = { ...obj1, ...obj2 }

JavaScript ES6的超級好用功能「Spread Operator」,直接新建const obj3

會直接將obj1和obj2的key-value pair複製到新建立的obj3

如果obj1和obj2有相同的key,則後者(obj2)會取代前者,範例如下:

const obj1 = { name: "Eide", love: "Pekora" };
const obj2 = { pet: "hamster", name: "DanDan" };
const obj3 = { ...obj1, ...obj2 };
console.log(obj3);

//output,注意name的變化
// { name: 'DanDan', love: 'Pekora', pet: 'hamster' }



object新增、修改、刪除key-value

given an object: const obj = { a: "A", b: [ 1, 2, 3], c: someFunction }

新增:obj.d = "Create new key d"

修改:obj.a = "modified_A"

刪除:delete obj.b or delete obj["b"]

範例如下:

const obj = {
  a: "A",
  b: [1, 2, 3],
  c: function (props) {
    console.log(props);
  },
};
obj.a = "modified_A";
obj.d = "Create new key d";
delete obj["b"];
console.log(obj);

//output
// { a: 'modified_A', c: [Function: c], d: 'Create new key d' }



object遍歷

array有順序性,以index來查找。然而object以key作為查找,沒有所謂的順序或排序,Object不可迭代!!!

有鑑於此,Object著重在key的操作運算上


for...in...: for( let key in obj ) { do something }

for迴圈的一種,但注意這裡的key,雖然是抓obj的key沒錯,但它是一個String

所以如果你使用obj.key,會是undefined的

範例如下:

const obj = {
  a: "A",
  b: [1, 2, 3],
  c: function (props) {
    console.log(props);
  },
};
for (let key in obj) {
  console.log(key);
  console.log(typeof key);
  console.log(obj.key);
  console.log(obj[key]);
  console.log("=======================");
}

//output
a
string
undefined
A
=======================
b
string
undefined
[ 1, 2, 3 ]
=======================
c
string
undefined
[Function: c]
=======================


for...of...配合Object.entries():for ( const [key, value] of Object.entries(obj)) { do something }

先說明Object.entries(obj)的功能,Object.entries(obj)將obj內各個key-value pair轉成陣列(Array)

舉例來說:

const obj = {
  a: "A",
  b: [1, 2, 3],
  c: function (props) {
    console.log(props);
  },
};
console.log(Object.entries(obj))

//output
[ [ 'a', 'A' ], [ 'b', [ 1, 2, 3 ] ], [ 'c', [Function: c] ] ]


因此實際上我們做的是針對一個Array做for...of...迴圈,以[ key, value ]相配應

簡單的範例輸出如下:

for (const [key, value] of Object.entries(obj)) {
  console.log(key);
  console.log(value);
  console.log("=======================");
}

//output
a
A
=======================
b
[ 1, 2, 3 ]
=======================
c
[Function: c]
=======================


記得注意Object的key-value pair沒有先後順序性,如果透過Object.entries()轉成陣列後,想要在for迴圈中依序有序地操作

則須改寫成for (const [key, value] of Object.entries(obj).sort(compare_function) { do something }

得先做好資料前處理的工作(排序)~



object的key查找

Object.keys():const keys_arr = Object.keys(obj)

Object.keys()回傳obj的所有key值組成的陣列,範例如下:

const obj = {
  a: "A",
  b: [1, 2, 3],
  c: function (props) {
    console.log(props);
  },
};
console.log(Object.keys(obj))

//output
[ 'a', 'b', 'c' ]



===待續 Ovo===

© 2021 Hamsterism. All rights reserved github