Array API

1. Array Properties

1.1. length

var fruits = ["Banana", "Orange", "Apple", "Mango"];
console.log(fruits.length); //4

2. Is Array

There are 3 solutions:

2.1. Built-in isArray()

NOTE: Supported with ECMAScript 5 or newer

var x = 1;
var ary = ['Apple', 'Banana', 'Cake'];
console.log( Array.isArray(x) );  // false
console.log( Array.isArray(ary) );  // true

2.2. Self-Defined isArray() via constructor

var x = 1;
console.log( x.constructor ); // ƒ Number() { [native code] }
console.log( isArray(x) );    // false

var ary = ['Apple', 'Banana', 'Cake'];
console.log( ary.constructor ); // ƒ Array() { [native code] }
console.log( isArray(ary) );  // true

function isArray(x) {
    return x.constructor.toString().indexOf("Array") > -1;
}

Anthor simpler solution:

function isArray(myArray) {
    return myArray.constructor === Array;
}

2.3. instanceof Array

var ary = ['Apple', 'Banana', 'Cake'];
console.log( ary instanceof Array );  // true

3. To String

3.1. toString()

var ary = ['Apple', 'Banana', 'Cake'];
console.log( ary );         // ["Apple", "Banana", "Cake"]
console.log( ary.toString() );    // "Apple,Banana,Cake"

3.2. join()

join(sign)

類似 toString() ,可指定串聯符號

var ary = ['Apple', 'Banana', 'Cake'];
console.log( ary.join('-*-') );   // "Apple-*-Banana-*-Cake"

4. Add Elements

4.1. push()

push(item)

Add an element into an array at the end, and return the new array length.

var fruits = ["Banana", "Orange", "Apple", "Mango"];
console.log(fruits);    //["Banana", "Orange", "Apple", "Mango"]
var x = fruits.push("Lemon");
console.log(fruits);    //["Banana", "Orange", "Apple", "Mango", "Lemon"]
console.log(x);            //5

4.2. unshift()

unshift(item)

Add an element into an array at the beginning, and return the new array length.

var fruits = ["Banana", "Orange", "Apple", "Mango"];
console.log(fruits);    //["Banana", "Orange", "Apple", "Mango"]
var x = fruits.unshift("Lemon");
console.log(fruits);    //["Lemon", "Banana", "Orange", "Apple", "Mango"]
console.log(x);            //5

4.3. directly assign/append via index

WARNING: 如果指定的 index 有跳號,會造成中間出現 undefined (Adding elements with high indexes can create undefined "holes" in an array)

var fruits = ["Banana", "Orange", "Apple", "Mango"];
console.log(fruits);        //["Banana", "Orange", "Apple", "Mango"]
console.log(fruits.length); //4

fruits[4] ="Lemon";
console.log(fruits);        //["Banana", "Orange", "Apple", "Mango", "Lemon"]
console.log(fruits.length);    //5

fruits[10] ="Lemon";
console.log(fruits);        //["Banana", "Orange", "Apple", "Mango", empty × 5, "Lemon"]
console.log(fruits.length);    //11
console.log(fruits[8]);        //undefined

5. Remove Elements

5.1. pop()

Remove the last element, and return the removed element.

var fruits = ["Banana", "Orange", "Apple", "Mango"];
console.log(fruits);    // ["Banana", "Orange", "Apple", "Mango"]
var item = fruits.pop();
console.log(fruits);    // ["Banana", "Orange", "Apple"]
console.log(item);        // "Mango"

5.2. shift()

Remove the first element, and return the removed element.

var fruits = ["Banana", "Orange", "Apple", "Mango"];
console.log(fruits);    // ["Banana", "Orange", "Apple", "Mango"]
var item = fruits.shift();
console.log(fruits);    // ["Orange", "Apple", "Mango"]
console.log(item);        // "Banana"

5.3. using delete

Using delete may leave undefined holes in the array. Use pop() or shift() instead.

var fruits = ["Banana", "Orange", "Apple", "Mango"];
console.log(fruits);    // ["Banana", "Orange", "Apple", "Mango"]
delete fruits[2];
console.log(fruits);    // ["Banana", "Orange", empty, "Mango"]
console.log(fruits[2]);    // undefined

6. Splice (Add & Remove Elements Once)

6.1. splice()

splice(insertPosition, removedCount, [addedItem1, addedItem2, ...])

// demo 1: add
var fruits = ["Item0", "Item1", "Item2", "Item3"];
var x = fruits.splice(2, 0, "New1", "New2");
console.log(fruits);  // ["Item0", "Item1", "New1", "New2", "Item2", "Item3"]
console.log(x);     // []

// demo 2: remove
var fruits = ["Item0", "Item1", "Item2", "Item3"];
var x = fruits.splice(1, 5);
console.log(fruits);  // ["Item0"]
console.log(x);     // ["Item1", "Item2", "Item3"]

// demo 3: add + remove
var fruits = ["Item0", "Item1", "Item2", "Item3"];
var x = fruits.splice(1, 2, "New1");
console.log(fruits);  // ["Item0", "New1", "Item3"]
console.log(x);     // ["Item1", "Item2"]

// demo 4: negative-position example
var fruits = ["Item0", "Item1", "Item2", "Item3"];
var x = fruits.splice(-1, 5);
console.log(fruits);  // ["Item0", "Item1", "Item2"]
console.log(x);     // ["Item3"]

7. Merge Arrays

7.1. concat()

concat() does not change the existing arrays. It always returns a new array.

var ary1 = ["Cecilie", "Lone"];
var ary2 = ["Emil", "Tobias", "Linus"];
var ary3 = ["Robin", "Morgan"];
var aryFinal = ary1.concat(ary2, ary3);
console.log(aryFinal);  //["Cecilie", "Lone", "Emil", "Tobias", "Linus", "Robin", "Morgan"]
console.log(ary1);    //["Cecilie", "Lone"]
console.log(ary2);    //["Emil", "Tobias", "Linus"]
console.log(ary3);    //["Robin", "Morgan"]

8. Fetch Sub-Array

8.1. slice()

slice(startIndex, [endIndexExcluded])

  • slice() creates a new array. It does not remove any elements from the source array.
  • The element of endIndex not included.
var fruits = ["Item0", "Item1", "Item2", "Item3", "Item4"];
console.log( fruits.slice(2) );   //["Item2", "Item3", "Item4"]
console.log( fruits.slice(1, 3) );  //["Item1", "Item2"]
console.log( fruits );        //["Item0", "Item1", "Item2", "Item3", "Item4"]

9. Find Max and Min

  • There are no built-in functions for finding the highest or lowest value in a JavaScript array.
  • 但可以用其他技巧做到

9.1. 1. using sort()

  • Cons: inefficient
    • Sorting a whole array is a very inefficient method if you only want to find the highest (or lowest) value.
var points = [40, 100, 1, 5, 25, 10];
points.sort(function(a, b){return a - b});
console.log(points[0]); // 1 (the lowest value)
console.log(points[points.length-1]); //100 (the highest value)

9.2. 2. using Math.max().apply()

var points = [40, 100, 1, 5, 25, 10];
console.log( Math.max.apply(null, points) ); //100
console.log( Math.min.apply(null, points) ); //1

9.3. 3. using Array.prototype.reduce()

var maxCbk = ( max, cur ) => Math.max( max, cur );
var minCbk = ( max, cur ) => Math.min( max, cur );

var points = [40, 100, 1, 5, 25, 10];
console.log( points.reduce(maxCbk) ); //100
console.log( points.reduce(minCbk) ); //1

9.4. 4. using "home made" method

The fastest solution?

function myArrayMax(arr) {
    var len = arr.length
    var max = -Infinity;
    while (len--) {
        if (arr[len] > max) {
            max = arr[len];
        }
    }
    return max;
}

function myArrayMin(arr) {
    var len = arr.length
    var min = Infinity;
    while (len--) {
        if (arr[len] < min) {
            min = arr[len];
        }
    }
    return min;
}

10.1. indexOf()

var fruits = ["Banana", "Orange", "Apple", "Mango", "Apple"];
console.log( fruits.indexOf("Apple") ); //2
console.log( fruits.indexOf("Car") ); //-1

10.2. lastIndexOf()

var fruits = ["Banana", "Orange", "Apple", "Mango", "Apple"];
console.log( fruits.lastIndexOf("Apple") ); //4
console.log( fruits.lastIndexOf("Car") ); //-1

10.3. includes()

var a = [1, 2, 3];
console.log(a.includes(2)); // true
console.log(a.includes(4)) // false

11. Sort

11.1. reverse()

  • 純反轉,不針對內容排序
var fruits = ["Banana", "Orange", "Apple", "Mango"];
fruits.reverse();
console.log( fruits );  // ["Mango", "Apple", "Orange", "Banana"]

11.2. sort() for strings (ascent)

  • 針對內容排序
  • numerically vs. alphabetically sorting: sort() sorts values as strings. (alphabetically)
  • sort() will change the array, and return sorted result too.
var fruits = ["Banana", "Orange", "Apple", "Mango"];
var x = fruits.sort();
console.log( fruits );  // ["Apple", "Banana", "Mango", "Orange"]
console.log( x );       // ["Apple", "Banana", "Mango", "Orange"]

11.3. sorting strings (descend)

sort() + reverse()

var fruits = ["Banana", "Orange", "Apple", "Mango"];
fruits.sort();
fruits.reverse();
console.log( fruits );  // ["Orange", "Mango", "Banana", "Apple"]

11.4. sorting numbers

sort numbers using default sort() will get incorrect result

var numAry = [3, 5, 11, 4, 9];
numAry.sort();
console.log(numAry); //  [11, 3, 4, 5, 9]

Numeric Sort Solution: providing a compare function

// ascend
var numAry = [3, 5, 11, 4, 9];
numAry.sort(function(a, b){return a - b});
console.log(numAry); //  [3, 4, 5, 9, 11]

//descend
var numAry = [3, 5, 11, 4, 9];
numAry.sort(function(a, b){return b - a});
console.log(numAry); //   [11, 9, 5, 4, 3]

// random
var numAry = [3, 5, 11, 4, 9];
numAry.sort(function(a, b){return 0.5 - Math.random()});

11.5. sorting Object Arrays

using compare function

var cars = [
{type:"Volvo", year:2016},
{type:"Saab", year:2001},
{type:"BMW", year:2010}];

// sort by number property
cars.sort(function(a, b){return a.year - b.year});
console.log(cars);  //[0]Saab 2001, [1]BMW 2010, [2]Volvo 2016

// sort by string property
cars.sort(function(a, b){
    var x = a.type.toLowerCase();
    var y = b.type.toLowerCase();
    if (x < y) {return -1;}
    if (x > y) {return 1;}
    return 0;
});
console.log(cars);  //[0]BMW 2010, [1] Saab 2001, [2]Volvo 2016

11.6. Compare Function

  • Purpose: define an alternative sort order
  • Return: should return a negative, zero, or positive value, depending on the arguments

Example:

// ascend
var numAry = [3, 5, 11, 4, 9];
numAry.sort(function(a, b){return a - b}); // The Compare Function
console.log(numAry); //  [3, 4, 5, 9, 11]

When comparing 40 and 100

  1. the sort() method calls the compare function(40,100).
  2. The function calculates 40-100, and returns -60 (a negative value).
  3. The sort function will sort 40 as a value lower than 100.

12. Array Prototype API

12.1. Array.prototype.forEach()

ref: https://developer.mozilla.org/zh-TW/docs/Web/JavaScript/Reference/Global_Objects/Array/forEach

var newArray = oldAry.forEach(callback[, thisArg])

  • callback: 有3個參數:
    • currentValue: 目前處理的元素值
    • index: 目前處理元素的陣列索引
    • array: 呼叫此方法的陣列
  • thisArg (optional): 執行 callback 的 this 值
var array1 = ['a', 'b', 'c'];
array1.forEach(function(el) {
  console.log(el);
});

12.2. Array.prototype.map()

ref: https://developer.mozilla.org/zh-TW/docs/Web/JavaScript/Reference/Global_Objects/Array/map

巡訪每個元素,逐一加工後回傳

var newArray = oldAry.map(callback[, thisArg])

  • callback: 有3個參數:
    • currentValue: 目前處理的元素值
    • index: 目前處理元素的陣列索引
    • array: 呼叫此方法的陣列
  • thisArg (optional): 執行 callback 的 this 值

Example:

var origAry = [1, 5, 10, 15];
var newAry = origAry.map(function(currentValue, index, array) {
  console.log(`currentValue=[${currentValue}] index=[${index}], array=[${array}]`);
    return currentValue * 2;
});

console.log(origAry); // [1, 5, 10, 15]
console.log(newAry);  // [2, 10, 20, 30]

// ***** result *****
// currentValue=[1] index=[0], array=[1,5,10,15]
// currentValue=[5] index=[1], array=[1,5,10,15]
// currentValue=[10] index=[2], array=[1,5,10,15]
// currentValue=[15] index=[3], array=[1,5,10,15]
// (4) [1, 5, 10, 15]
// (4) [2, 10, 20, 30]

Using ES6 Arrow Function Syntax, it'll be more concise:

var origAry = [1, 5, 10, 15];
var newAry = origAry.map((x) => x * 2);

console.log(origAry); // [1, 5, 10, 15]
console.log(newAry);  // [2, 10, 20, 30]

12.3. Array.prototype.filter()

ref: https://developer.mozilla.org/zh-TW/docs/Web/JavaScript/Reference/Global_Objects/Array/filter

過濾,巡訪每個元素,逐一判斷是否保留,回傳布林

var newArray = oldAry.filter(callback[, thisArg])

  • callback: 有3個參數:
    • currentValue: 目前處理的元素值
    • index: 目前處理元素的陣列索引
    • array: 呼叫此方法的陣列
  • thisArg (optional): 執行 callback 的 this 值
var origAry = ['12345', '1', '1234', '123', '12'];
var newAry = origAry.filter(x => x.length > 3);

console.log(origAry); // ["12345", "1", "1234", "123", "12"]
console.log(newAry);  //["12345", "1234"]

12.4. Array.prototype.reduce()

ref: https://developer.mozilla.org/zh-TW/docs/Web/JavaScript/Reference/Global_Objects/Array/Reduce

利用一個累加器及陣列中每項元素,將陣列化為單一值

var newArray = oldAry.reduce(callback[accumlator, currentValue, currentIndex, array], initialValue)

  • callback: 有4個參數:
    • accumulator: 用來累積回呼函式回傳值的累加器或 initialValue(若有的話)。累加器是上一次呼叫後,所回傳的累加數值。
    • currentValue: 目前處理的元素值
    • index: 目前處理元素的陣列索引
    • array: 呼叫此方法的陣列
  • initialValue (optional): 累加器初始值。建議提供比較保險
    • 若沒有提供初始值,則會用原陣列的第一個元素當作初始值,並且跳過第一個元素(index=0)的處理
    • 假如於一個空陣列呼叫 reduce() 方法,且沒有提供累加器初始值,將會發生錯誤

Example 1: 陣列值加總

無 initialValue:

var rlt = [1, 2, 3, 4, 5].reduce(
  (accumulator, currentValue, currentIndex, array) => {
    return accumulator + currentValue;
  }
);
console.log(rlt); //15

有 initialValue:

var rlt = [1, 2, 3, 4, 5].reduce(
  (accumulator, currentValue, currentIndex, array) => {
    return accumulator + currentValue;
  },10
);
console.log(rlt); //25

也可以如下寫法:

var cbk = (accumulator, currentValue, currentIndex, array) => {
    return accumulator + currentValue;
};
console.log( [1, 2, 3, 4, 5].reduce(cbk) );     // 15
console.log( [1, 2, 3, 4, 5].reduce(cbk, 10) ); // 25

ES6 語法簡寫:

var cbk = (accumulator, currentValue) => accumulator + currentValue;
console.log( [1, 2, 3, 4, 5].reduce(cbk) );
console.log( [1, 2, 3, 4, 5].reduce(cbk, 10) );

Example 2: 比較物件屬性大小

var maxCallback = ( acc, curEl, curIdx, ary ) => {
    console.log(`curIdx=[${curIdx}]`);
    return (acc.x > curEl.x) ? acc : curEl;
};

console.log( [ { x: 22 }, { x: 42 } ].reduce( maxCallback) ); // { x: 42 }
console.log( [ { x: 22 }, { x: 42 } ].reduce( maxCallback, { x: 50 } ) ); // { x: 50 }
console.log( [ { x: 22 }            ].reduce( maxCallback) ); // { x: 22 }
console.log( [                      ].reduce( maxCallback) ); // TypeError

如果純粹比較大小想取最終值,以下寫法比較好:

// map/reduce; better solution, also works for empty or larger arrays
var maxCallback2 = ( max, cur ) => Math.max( max, cur );
var rlt = [ { x: 22 }, { x: 42 } ].map( el => el.x )
                        .reduce( maxCallback2, -Infinity );
console.log(rlt); //42

12.5. Array.prototype.every()

ref: https://developer.mozilla.org/zh-TW/docs/Web/JavaScript/Reference/Global_Objects/Array/every

巡訪每個元素,測試是否每一個元素都通過條件(只要遇到不合格的就會停下來並回傳 false)

var bool = arr.every(callback[, thisArg])

  • callback: 有3個參數:
    • currentValue: 目前處理的元素值
    • index: 目前處理元素的陣列索引
    • array: 呼叫此方法的陣列
  • thisArg (optional): 執行 callback 的 this 值

Example:

var numbers = [24, 19, 16, 25, 29];
var allPass = numbers.every(myFunction);
function myFunction(value, index, array) {
    console.log(`index=[${index}] value=[${value}]`);
    return value > 18;
}
console.log(`allPass=[${allPass}]`);

// ======== result:
// index=[0] value=[24]
// index=[1] value=[19]
// index=[2] value=[16]
// allPass=[false]

ES6 syntax:

var allPass = [24, 19, 16, 25, 29].every(val => val > 18);

results matching ""

    No results matching ""