閱讀《資料結構與演算法 JavaScript 描述 第二版》之陣列

語言: CN / TW / HK

文章中程式碼不一定是來自書籍,根據自己的理解書寫,目的是熟悉 JS 基礎資料結構和演算法。

概述

JS 陣列無需自己實現,但需要掌握 JS 內建方法。JS 本身提供了眾多的 API 運算元組,在 ES5+ 之後增了更多的陣列的操作方法,對第三方庫如 lodash 等函式庫依賴越來越少了。

JS 陣列定義

  • 標準定義:儲存元素的線性集合。
  • JS 陣列是物件,儲存元素,是非線性
  • 通過索引訪問

使用陣列

建立陣列

js let numbers = []; // 初始化 let nums = [1, 2, 3]; // 初始化有元素 let ns = new Array(); // 使用建構函式 let ns10 = new Array(10); // 指定長度

讀寫陣列

  • 使用下標讀取
  • 使用 = 訪問

js let arr = [1, 2, 3]; let arr1 = arr[0] arr[0] = 123

字串生成陣列

js let date = '2022-09-10'; let dateArr = date.split('-'); // [ '2022', '09', '10' ]

對陣列的整體性操作

  • 陣列的淺複製 (引用地址相同)
  • 陣列的深複製(引用地址不相同)

存取函式

訪問陣列的函式

查詢元素

  • indexOf/lastIndexOf 查詢元素

```js let a = ['a', 'b', 'c'] let aIndex = a.indexOf("b") // 1

let b = ['a1', 'b1', 'c1', 'a1'] let a1Index = b.indexOf('a1') // 3 let a1LastIndex = b.lastIndexOf('a1') // 0 ```

陣列的字串表示方法

  • join 拼接成字串
  • toString 內建支援變化成字串方法

js let b = ['a1', 'b1', 'c1', 'a1'] b.join("-") // 'a1-b1-c1-a1' b.toString() // 'a1,b1,c1,a1'

由已有陣列建立新陣列

  • concat
  • splice

```js let c = ['a', 'b'] c.concat('c') // [ 'a', 'b', 'c' ]

let d = ['a', 'c'] d.splice(1, 0, 'b') // d: [ 'a', 'b', 'c' ] ```

可變函式

為陣列新增元素

  • push
  • unshift

js let e = ['a', 'b'] e.push('c') // 返回長度 3, e 陣列的值是: [ 'a', 'b', 'c' ] e.unshift('c') // 返回長度是4, e 陣列的值是:[ 'c', 'a', 'b', 'c' ]

從陣列中刪除元素

  • pop
  • shift

```js let a = [1,3,5,7] a.pop() // 返回是 7, 陣列 a: [ 1, 3, 5 ]

let b = [1,3,5,7] b.shift() // 返回是 1, 陣列 a: [ 3, 5, 7 ] ```

從陣列中間位置新增和刪除元素

  • splice

js let b = [1,2,3,4,5] b.splice(2,0, 'this is splice add str'); // b [ 1, 2, 'this is splice add str', 3, 4, 5 ]

為陣列排序

  • reserve
  • sort

迭代方法

不生成新陣列的迭代器方法

  • forEach
  • every
  • some
  • reduce/reduceRight
  • map/filter

```js let b = [1,2,3,4,5] b.forEach(a => {console.log(a)}) // 1 2 3 4 5

let b = [1,2,3,4,5] // false b.some((e) => e === 1) // true b.reduce((a, c) => a + c) // 15 b.reduceRight((a, c) => a + c) // 15

let a = [1, 2, 3, 4, 5] a.map((aa) => aa + 1) // [ 2, 3, 4, 5, 6 ]

let afterFilter = a.filter((aa) => aa != 3) // [ 1, 2, 4, 5 ] ```

生成新陣列的迭代器方法

  • map 生成一個新的陣列
  • filter 生成符合條件的新陣列

二維和多維陣列

建立二維陣列

  • 陣列 + for

```js let arr = [] let rows = 5;

for (let i = 0; i < rows; ++i) { arr[i] = [] } // arr [ [], [], [], [], [] ] ```

處理二維陣列的元素

雙層 for 迴圈:

  • 按照列訪問
  • 按照行訪問

參差不齊的陣列

雙層 for 迴圈。 針對參差不齊的陣列,for 迴圈的特點是:使用陣列的長度,作為迴圈的上限。

```js let arr = [[1, 2], [3, 4, 5], [6, 7, 8]];

for (let i = 0; i < arr.length; ++i) { for (let j = 0; j < arr[0].length; ++j) { console.log("val:", arr[i][j]) } } ```

物件陣列

在陣列中儲存,除去基本資料結構以外的引用資料型別。在陣列中儲存複雜資料型別。

```js function Point(x, y) { this.x = x; this.y = y; }

let pArr = []

pArr.push(new Point(1, 2)) pArr.push(new Point(3, 4)) ```

物件中的陣列

一個常見的例子就是:

```js function DateStore() { this.store = [] }

DateStore.prototype.add = function(content) { this.store.push(content) }

let ax = new DateStore()

ax.add('flex')

console.log(ax.store) // ['flex'] ```

一個使用 JavaScript 通過原型鏈定義 add 方法,實現建構函式

小結

  • 陣列在資料結構中佔據重要位置。
  • 陣列作為 JavaScript 的引用型別,在於後端互動時常用資料型別,熟悉相關的操作十分重要。
  • 陣列是 JavaScript 內建型別支援,與 Java 等其他語言定義的陣列有所區別。
  • 熟練 JavaScript 陣列的各種函式操作。
  • 瞭解 JavaScript 多維陣列。