[ 筆記 ] JavaScript - 01 陣列


Posted by krebikshaw on 2020-06-18

陣列 length 的規範

  • 假設陣列中有兩個 , 間沒有值,會判定為 undifined,但依然會算進 length 中。
  • 最後一個元素尾端多一個 , 是被允許的。
var arr1 = [1,,3]  
// arr1[1] = undefined    arr.length = 3

var arr2 = [,,]
// arr2.length = 2  陣列允許額外的尾端逗號,所以 length 不是 3

陣列的特殊之處

  • 當我們在陣列中指定一個位置它是小於 2的32次方的非負整數(即特性索引),並填入一個數值,length 會自動補上
var arr = [1,2,3] // 此時的 length = 3

arr[10] = 0       // 我在陣列的編號 10 位置放入 0 這個值
console.log(arr.length)  // 11  ,length 會被補成 11

arr = [ 1, 2, 3, <7 empty items>, 0 ]
  • 像這種含有 empty items 的陣列稱作 稀疏陣列
  • 若是我們想索引中間不存在的值 console.log(Object.prototype.toString.call(arr[5])) 會回傳 undefined

為了要讓這個條件 length長度永遠大於陣列最高索引數 永遠成立。
一陣列 arr[i] = x,如果i 大於 arr.length,length 會被設為 i+1

  • 如果將length設為 i,並且小於目前值,length會把大於a[i]的值刪掉
var arr = [1,2,3]
arr[10] = 0      // 此時 length 會被補為 11

arr.length = 5   // 若我現在將 length 強制改成 5
arr = [1,2,3,<2 empty items>]  // arr[10] 的值會被砍掉

arr.length = 0   // 若我再把 length 強制改成 0,再改回 5
arr.length = 5   
arr = [,,,,]     // 會變成 length = 5 但沒有元素

新增 & 刪除元素

arr[i] = x:將資料 x 新增到位置 i

var arr = []
arr[0] = "zero"
arr[1] = "one"

arr = ["zero", "one"]

delete arr[i]:將位置 i 的資料刪除

  • 這邊說得將 資料 刪除,意思是那個元素會變成 undefined
var arr = ["zero", "one"]
delete arr[1]
arr.length   // 2   
arr = ["zero", <1 empty items>]

注意:刪除一陣列元素相似於指定 undefined 給該元素,length並不會改變

若要將 稀疏陣列 的 empty items 清理乾淨,可以運用下列方式:

// 欲把 arr1(稀疏陣列)中的可用元素複製到 arr2
var arr1 =  [1, 2, undefined, null, 3, 4, 5, , ,];
var arr2 = []

// if裡的條件式視篩選的性質而定
for (var i=0; i<arr1.length; i++) {
    if (!arr1[i]) continue // 如果該元素為null、undefined、空元素就跳過!
    arr2.push(arr1[i])
}

arr2 = [1, 2, 3, 4, 5]

Array.prototype 定義的實用陣列操作函式

  • Array.prototype 定義的陣列操作函式,是任何陣列都可以使用的。

Array.join() :把所有元素轉成字串,串接回傳結果字串(預設用逗號分割)

  • 會將陣列轉換成字串
    var arr = [1,2,3]
    arr.join()    //  "1,2,3"
    arr.join("")  //  "123"
    arr.join(" ") //  "1 2 3"
    

Array.reverse() :倒轉陣列元素的順序,並回傳結果

  • 不會建立新的陣列
    var arr = [1,2,3]
    arr.reverse()    // [3,2,1]
    

Array.sort() :重新排列陣列的元素順序

  • 不會建立新的陣列

  • 對字母排序,會依照 a ~ z 來排

    var arr = ["banana","apple", "candy"
    arr.sort()   //  arr = ["apple", "banana", "orange"]
    
  • 對數字做排序,會一個一個數字比下去

    var arr = [10,2,1,3,5]
    arr.sort()    //  arr = [1, 10, 2, 3, 5]
    

    因為數字會被先轉換成字串,在Unicode順序中”10”在”2”前面,所以當遇到數字元素的比較時,我們需要使用傳入函式的方式:

    var arr = [10,2,1,3,5]
    arr.sort(function(a,b) {
      return a - b
    })            //  arr = [ 1, 2, 3, 5, 10 ]
    

Array.concat() :把引數值加入並 回傳一個新陣列

  • 不改變原本陣列的內容
  • 如果引數值有陣列,那就串接陣列元素而非陣列本身
    var arr1 = [1,2,3];
    var arr2 = arr1.concat(4,5);         // [1, 2, 3, 4, 5]
    var arr3 = arr1.concat([4,5]);       // [1, 2, 3, 4, 5]
    var arr4 = arr1.concat([4,5],[6,7]); // [1, 2, 3, 4, 5, 6, 7]
    var arr5 = arr1.concat(4,[5,[6,7]]); // [1, 2, 3, 4, 5, [6, 7]]
    console.log(arr1)                    // [1,2,3] 原本的陣列依然不變
    

Array.slice() :回傳擷取出的元素

  • 不會改變原本陣列的內容
  • 只有一個引數時,即回傳引數後的所有元素(包含自己),序從0開始

    var arr1 = [1,2,3,4,5,6];
    
    //只有一個引數時,會擷取引數之後的全部
    console.log(arr1.slice(2))  // [ 3, 4, 5, 6 ] 
    console.log(arr1)           // [1,2,3,4,5,6]  arr1 的值不會變
    
  • 兩個引數時(x,y),回傳x後方(包含x)、y前方的元素
    如果有任何一個引數值是負的,代表從反序算起(倒數)

    var arr1 = [1,2,3,4,5,6,7,8];
    
    //兩個引數,會回傳x後方(包含x)、y前方的元素
    console.log(arr1.slice(2,4))  // [ 3, 4 ]
    console.log(arr1.slice(2,-2)) // [ 3, 4, 5, 6 ]
    console.log(arr1.slice(-5,-2))// [ 4, 5, 6 ]
    

Array.splice() :回傳擷取出的元素,也可以在指定位置插入新元素

  • 不會建立新的陣列,但擷取出元素後,會把這些元素 從原本的陣列中刪除
  • 有三個參數可以填
    1. 第一個參數:起始位置 (如果只有一個參數,代表起始位置後面元素全刪除)
    2. 第二個參數:要擷取的個數
    3. 第三個參數以後:要加入的新元素
var arr1 = [1,2,3,4,5,6,7,8];

var arr2 = arr1.splice(1, 2, [11, 22])
// 從位置 1 刪掉兩個元素,填入一個元素 [11,22] ,把刪除的部分回傳出去給 arr2 

console.log(arr2) // [ 2, 3 ]  arr2 會接收到 arr1 回傳出來的元素
console.log(arr1) // [ 1, [ 11, 22 ], 4, 5, 6, 7, 8 ]

Array.push() & Array.pop()

  • 不會重新創建一個新陣列
  • push():會在陣列尾端加一個或多個元素,並 回傳新陣列長度
  • pop(): 則是刪除陣列最後一個元素,並 回傳他移除的值

    var arr1 = []; 
    var num1 = arr1.push(1,3,5,7)
    
    console.log(arr1) //[1, 3, 5, 7]
    console.log(num1)  // 4 陣列的長度
    
    var num2 = arr1.pop()
    
    console.log(arr1)  //[1, 3, 5]
    console.log(num2)  // 7 最後一個被刪掉的值
    

Array.unshift() & Array.shift()

  • 不會重新創建一個新陣列
  • unshift():會在陣列開頭加入一個或多個元素,並 回傳新陣列長度
  • shift:則是刪除陣列第一個元素,並 回傳他移除的值

    var arr1 = [1,2,3,4];
    var num1 = arr1.unshift(5)
    
    console.log(arr1) // [ 5, 1, 2, 3, 4 ]
    console.log(num1)  // 5 陣列 length 的值
    
    var num2 = arr1.shift()
    
    console.log(arr1)  // [ 1, 2, 3, 4 ]
    console.log(num2)  // 5 第一個被刪掉的值
    

Array.toString() :把陣列元素轉成字串,用逗號分隔輸出一字串

  • Array.join( )不帶引數時,也會傳回一樣的結果
    var arr1 = [1,[2, 3], 4]
    arr1.toString()     // "1, 2, 3, 4"
    

Array.toLocaleString( ) :可以將內容轉換成不同表示方法

var num = 123456.789;

num.toLocaleString("en-IN"); 
// "123,456.789"
num.toLocaleString("zh-Hans-CN-u-nu-hanidec"); 
// "一二三,四五六.七八九"
num.toLocaleString("ja-JP", {style: "currency", currency: "JPY"}); 
// "¥123,457"

EMCAScript 5 陣列方法

ECMAScript5 定義了幾個新的陣列方法來迭代(interating)、對映(mapping)、過濾(filtering)、測試、約簡(reducing),以及搜尋陣列。

這些方法的第一個引數大多是個函式,他們會對陣列中的每個元素都調用一次此函式,函式會用三個引數來調用:陣列元素值、該元素的索引、陣列本身,通常你只需要這些第一個引數,可以忽略第二或第三引數。

所有的 EMCAScript5 的陣列方法都不會修改調用他們的陣列

Array.forEach():逐一查用陣列元素,並對每個元素調用指定的函式

  • 注意forEach()並沒有提供普通for迴圈的break來提前結束。

    var data = [1,2,3,4,5];
    var sum = 0;
    
    // 計算陣列元素的總合---------
    //                    元素值
    data.forEach(function(value) {
    sum += value;
    });
    sum // 15
    
    // 遞增每個元素---------------
    //                   元素值, 索引, 陣列本身
    data.forEach(function(value, num, arr) {
    arr[num] = value + 1;
    })
    data // [2, 3, 4, 5, 6]
    

Array.map():逐一查用陣列元素,並對每個元素調用指定的函式,回傳結果成一個新陣列

  • 如果陣列是稀疏的,回傳的結果陣列也會同樣稀疏
    var a = [1,2,3, ,];
    var b = a.map(function(x) {
    return x * x; 
    })
    b // [1, 4, 9, undefined]
    

Array.filter():函式結果為true,篩選後的元素則被取出,組成一個新陣列回傳

  • filter( ) 會跳過稀疏陣列的缺口,回傳值永遠都會是密集的
    var arr1 = [1,2,3,4,5];
    var arr2 = a.filter(function(x) {
    return x > 2;
    });
    arr2 // [3, 4, 5]
    

Array.every() & Array.some()

  • 有點像邏輯運算的 && 與 ||, 將指定的函式套用在陣列元素上,回傳true或false
    • every( ):對所有陣列元素都是true,才回傳true (一找到false就停止)
    • some( ):只要有一元素是true,就回傳true (一找到true就結束)
var arr1 = [1,2,3,4,5];
var arr2 = arr1.every(function(x) {return x>3}); // false
var arr3 = arr1.some(function(x) {return x>3}); // true

Array.reduce():接收一個函式做累加,由左至右遍歷陣列元素,最後回傳一個結果值取兩個引數,一個是 動作函式,一個是 初始值(非必須)

var arr1 = [1,2,3,4,5];

//.reduce(function(回傳值,元素值) {}, 初始值);
arr1.reduce(function(x,y) { return x + y }, 10); // 25
次數 x 值 y 值 回傳值
第一次執行 初始值(10) 1 11
第二次執行 11 2 13
第三次執行 13 3 16
第四次執行 16 4 20
第五次執行 20 5 25
  • 第一次執行時,x 會隨著有無初始值而不同:
    • 有初始值(如上例) →x:初始值、y:Array[0]
    • 沒有初始值 → x:Array[0]、y:Array[1]

Array.indexOf() & Array.lastIndexOf():

  • 會根據指定的值在陣列中搜尋元素
    如果有找到,就返回第一個找到的索引值,沒有找到就回傳-1
    • Array.indexOf( ) 從陣列開頭開始找
    • Array.lastIndexOf( ) 從陣列尾端開始找
var arr1 = [1,2,3,2,5];
arr1.indexOf(2);     // 1
arr1.indexOf(10);    // -1
arr1.lastIndexOf(2); // 3

資料來源:JavaScript大全(第六版)


#javascript #Array #陣列







Related Posts

架站研究1

架站研究1

Spring @PathVariable vs @PathParam

Spring @PathVariable vs @PathParam

《嚴防後宮起火-以無聊宅宅的視角來理解版本控制的概念》

《嚴防後宮起火-以無聊宅宅的視角來理解版本控制的概念》


Comments