JavaScript 中的集合入門
簡介
數據組 不同形式的數據結構是大多數編程語言中的基本數據結構之一。在許多情況下,通過不同數據類型表示的數據組 被稱為 Collections .
在本指南中 - 我們將了解 JavaScript 中的集合 以及何時使用哪種類型的集合。三個主要的集合組 我們將看看:
- 索引集合
- 鍵控集合
- DOM 集合
索引集合
索引集合 是按索引列出的數據集合 . JavaScript 集合索引是 基於 0 的 ,這意味著它們從 0
開始 ,而不是 1
並上升到 n-1
, n
是集合中的對像數。 JavaScript有兩種索引集合Array
s 和 TypedArray
s.
數組對象
一個 Array
JavaScript 中的 object 是一個有序列表,可以使用索引訪問其元素。創建 Array
有多種方法 JavaScript 中的對象,在底層並沒有太大區別:
let myArray1 = [x1, x2, ... , xN];
let myArray2 = new Array(x1, x2, ... , xN);
let myArray3 = Array(x1, x2, ... , xN);
JavaScript 中的數組不是基於類型的,這意味著您不必事先定義數組的類型,也不必只添加同質元素:
let myArray = ["one", 1, "two", 2];
這是完全有效的語法,並且數組很樂意存儲對字符串和整數的引用。讓我們快速重新澄清一下數組的索引實際上是什麼:
let myArray = ["one", 1, "two", 2];
// 0 1 2 3 --> index values
所以從0
開始 最多 n-1
, 其中 n
是數組的長度。
每個數組都有一個名為 length
的屬性 . 長度 數組的大小是在數組初始化的同時確定的 .因此,當我們創建一個數組時,會為其 length
分配一個值 屬性。
此外,更改 長度 將更改數組。您可以通過縮短其長度來輕鬆截斷數組,並通過延長它來擴展它:
let myArray = ["one", 1, "two", 2];
console.log(myArray);
myArray.length = 5;
console.log(myArray);
myArray.length = 1;
console.log(myArray);
這導致:
["one", 1, "two", 2]
["one", 1, "two", 2, undefined]
["one"]
在 JavaScript 中,您可以創建一個沒有任何元素但有一定長度的數組。您可以將其視為分配 (保留)提前記憶。這正是我們通過更改 length
來擴展數組時的作用 比以前更大。
由於有三種方法可以創建填充元素的數組,因此也有三種方法可以創建分配內存的空數組,如下所示:
let myArray1 = new Array(4); // creates an array with 4 empty spaces
console.log(myArray1.length); // 4
let myArray2 = Array(4); // similar to the previous one, just without the keyword new
console.log(myArray2.length); // 4
let myArray3 = [];
myArray3.length = 4 // this one is a bit different, we assign the value to the property length
console.log(myArray3.length); // 4
到目前為止,這三種創建數組的方式除了語法上的差異外,沒有任何區別。
但是,如果您希望創建一個包含單個元素的數組,即 Number
,您必須使用方括號並定義具體元素,而不是數組的大小。
這是因為如果您將數字傳遞給 Array
構造函數,你將創建一個空數組並分配那麼多空間。
// New array with 10 spaces
let myArray1 = new Array(10)
// New array with a single element
let myArray3 = [10]
向數組添加元素
我們已經了解瞭如何創建 Array
,無論是空的還是非空的。現在讓我們看看如何向其中添加新元素。因為我們正在使用索引集合 我們將使用索引進行操作。
因為我們已經創建了一個 Array
4 個空元素,讓我們使用它。要添加一個元素,我們所要做的就是通過它的索引訪問元素 和賦值 給它:
let myArray1 = new Array(4)
myArray1[0] = "one"
myArray1[1] = "two"
myArray1[2] = "three"
myArray1[3] = "four"
console.log(myArray)
這將是輸出:
['one', 'two', 'three', 'four']
儘管我們在創建數組時為元素分配了 4 個空格,但在 JavaScript 中,Array
是動態製作的,這意味著您可以隨時縮小或擴大它們。
這意味著我們可以向 Array
添加更多元素 , 即使我們用 4 個空格“包圍”它:
myArray1[4] = "five"
myArray1[5] = "six"
console.log(myArray) // Output: ['one', 'two', 'three', 'four', 'five', 'six']
我們可以使用 for
輕鬆地遍歷數組 循環或 forEach
循環:
console.log('Traditional for loop:')
for (let i = 0; i < myArray1.length ; i++) {
console.log(myArray1[i]);
}
console.log('Functional forEach loop:')
myArray1.forEach( function (element){ console.log(element);});
這將輸出:
Traditional for loop:
one
two
three
four
five
six
Functional forEach loop:
one
two
three
four
five
six
數組方法
現在我們已經掌握了竅門,讓我們來試試內置的 Array
JavaScript 中的方法。您已經在前面的示例中看到了一個 - .forEach()
在 myArray1
上調用循環 .
讓我們回顧一下最常用的:
push()
- 在數組末尾添加一個元素
let myArray = [1,2,3];
myArray.push(4);
console.log(myArray); // outputs [1, 2, 3, 4]
pop()
- 刪除數組的最後一個元素
let myArray = [1,2,3,4];
myArray.pop();
console.log(myArray); // outputs [1, 2, 3]
concat()
- 將數組(兩個或更多)連接到一個數組中
// Concating 2 arrayslet myArray1 = [1,2,3]
let myArray2 = [4,5,6];
let finalArray1 = myArray1.concat(myArray2);
console.log(finalArray1); // [1,2,3,4,5,6]
// Concating 3 arrayslet
myArray3 = [7,8,9];
let finalArray2 = myArray1.concat(myArray2, myArray3);
console.log(finalArray2); // [1,2,3,4,5,6,7,8,9]
join(delimiter)
- 將所有元素連接成一個字符串,用delimiter
分隔
let myArray = ["Earth", "Wind", "Fire"];
let arrayString = myArray.join(",");
console.log(arrayString); // outputs Earth, Wind, Fire
// Bonus example
console.log(arrayString + "- September"); // outputs Earth, Wind, Fire - September
reverse()
- 正是這樣,顛倒了數組中元素的順序
let myArray = [1,2,3];
let reversed = myArray.reverse();
console.log(reversed); // [3,2,1]
slice(start, end)
- 從索引start
開始復制數組的一部分 直到索引end-1
let myArray = [1,2,3,4,5,6];
myArray = myArray.slice(3, 5);
console.log(myArray); // [4,5]
TypedArray 對象
Array
對象非常適合處理 JavaScript 中的任何數據類型,因為它可以將不同類型的元素存儲在一個數組中,並且具有操作這些元素的強大方法。
然而,當需要處理原始二進制數據時——那就是 TypedArray
對像開始發揮作用。例如在處理音頻和視頻時會處理原始數據。
TypedArray 的架構 對象
JavaScript 類型數組分為 buffers 和瀏覽量 .一個緩衝區 是一個只存儲一塊數據的對象,沒有訪問或操作該數據的方法。為了實現這一點,您必須使用 view - 它提供了一個上下文 ,一種將數據轉換為 TypedArray
的數據類型 .
一個緩衝區 通過 ArrayBuffer
實現 目的。它用於表示一個固定長度的二進制數據緩衝區。為了表示這個緩衝區,我們必須創建一個視圖 - DataView
- 它以所選格式表示該緩衝區。有多種類型的視圖,代表最常見的數字類型:
Int8Array
- 取值範圍 [-128, 127]UInt8Array
- 取值範圍 [0, 255],u 代表 unsignedInt16Array
- 取值範圍 [-32768, 32767]UInt16Array
- 取值範圍 [0, 65535]Float32Array
- 取值範圍 [1.2E-38, 3.4E38]
創建一個TypedArray
創建 TypedArray
時 某種類型的對象,我們實現了我們之前談到的——創建一個緩衝區和一個視圖。 TypedArray
沒有顯式構造函數 對象 - 沒有 new TypedArray()
語法——我們直接實例化我們需要的數組類型:
let tArray = new Int8Array(8);
在這裡,我們為 Int8Array
創建了一個緩衝區和一個視圖 大小為 8 個字節。對元素的賦值與 Array
相同 對象:
tArray[0] = 10;
console.log(tArray);
這將輸出:
Int8Array [ 10, 0, 0, 0, 0, 0, 0, 0 ]
免費電子書:Git Essentials
查看我們的 Git 學習實踐指南,其中包含最佳實踐、行業認可的標準以及隨附的備忘單。停止谷歌搜索 Git 命令並真正學習 它!
這樣,我們就可以填寫TypedArray
處理音頻或視頻時通常存在值,但不限於此 - 但這是一篇全新文章的主題。
鍵控集合
一個鍵控集合 是 key-value 中表示的數據集合 符號。元素的值通過它們各自的鍵來訪問和操作。
Map
s 和 Set
JavaScript 中的 s 可以有一個 value 歸因於單個鍵 ,儘管您可以通過歸因 List
來破解它 作為一個值,包含多個元素。仍然值得注意的是 List
它本身就是價值——而不是它的構成要素。
此外,鍵必須是唯一的 .
地圖對象
一個 Map
JavaScript 中的 object 是包含 鍵值對的標準映射 .創建一個新的 Map
對象,我們只需調用構造函數:
let myMap = new Map();
向地圖添加元素
一張空的地圖對我們沒有多大好處。讓我們通過 set()
向它添加一些元素 方法,它接受 key_name
它必須是一個字符串和一個 value
可以是任何類型:
myMap.set("one", 1);
myMap.set("two", 2);
myMap.set("three", "three");
console.log(myMap);
映射也是異構的,因此您不必對所有鍵都具有相同的值類型:
Map { 'one' => 1, 'two' => 2, 'three' => 'three' }
訪問地圖元素
要訪問 Map 的元素,我們只需 get()
他們,傳入 key_name
因為這些是地圖中的唯一標識符:
console.log(myMap.get("two")); // Output: 2
因為這個集合不是 基於索引,我們無法使用方括號訪問某些值:myMap["two"]
將返回一個 undefined
價值。
但是,如果我們調用 get(key_name)
不存在的鍵上的方法 ,返回值為 undefined
也是。
地圖方法
您將對地圖使用的主要兩種方法是 get()
和 set()
,但您還需要遍歷它們。 Map
類也有一個 forEach()
可以很容易地用於對所有條目進行迭代和執行操作。我們稍後會介紹它。
除了 forEach()
, 以下是 Maps 上最常用的方法:
-
set(key_name, value)
- 將鍵值對添加到Map
. -
get(key_name)
- 返回分配給傳遞的鍵的值,如果沒有這樣的鍵 - 返回undefined
. -
has(key_name)
- 返回true
或false
取決於是否有Map
有一個鍵key_name
與否:
console.log(myMap.has("two")); // true
console.log(myMap.has("five")) // false
delete(key_name)
- 根據傳遞的key_name
同時刪除key和value , 如果傳遞了一個不存在的鍵 - 什麼都不會發生:
myMap.delete("two")console.log(myMap);
// Output: Map { 'one' => 1, 'three' => 'three' }
myMap.delete("five")console.log(myMap);
// Output: Map { 'one' => 1, 'three' => 'three' }
clear()
- 從Map
中刪除每個鍵值對 對象:
myMap.clear();
console.log(myMap);
// Output: Map {}
Map
有一個主要屬性 - 它是 size
財產。它包含一個表示 Map
大小的數值 對象:
let myMap = new Map();
myMap.set("one", 1);
myMap.set("two", 2);
console.log(myMap.size);
// Output: 2
遍歷地圖
遍歷 Map
JavaScript 中的對像有點 Python 風格。我們可以使用 for..of
實現這一點的語法:
for (let [k, v] of myMap){
console.log(k + " written in number is " + v)
}
對於每個條目,使用 key-value 對([k, v]
) of myMap
, 做 ...
:
one written in number is 1
two written in number is 2
或者,我們可以使用功能更強大的 forEach()
方法:
myMap.forEach(function(value) { console.log(value);});
結果是:
1
2
three
或者,您可以同時檢索 value
和 key
:
myMap.forEach(function(value, key) { console.log(value, key);});
結果是:
1 one
2 two
three three
映射對象
自安Object
在 JavaScript 中也遵循鍵值表示法,可能很難決定使用哪個以及何時使用它。
關於這兩個的使用有幾個小技巧:
- 地圖 應該在 keys 時使用 直到運行時才知道 或者當所有鍵都是同一類型 並且所有值都是同一類型 .
- 對象 當存在對單個元素而不是元素集合進行操作的邏輯時,應使用該邏輯。
WeakMap 對象
一個WeakMap
JavaScript 中的對像是鍵值對的集合,其中 鍵是對象 only 和 values 可以是各種類型。名字弱 來自這些對像是垃圾收集目標的活動 - 這意味著如果沒有對它的引用,它將被刪除。
WeakMap
的 API 與 Map
相同 的 API,沒有任何迭代 作為weakmaps的方法是不可迭代的:
let myMap = new WeakMap();
let athlete = class Athlete{}
myMap.set(athlete, 1);
console.log(myMap.get(athlete))
這導致:
1
集合對象
一個Set
JavaScript 中的對像只是值的集合。這些值是唯一的,這意味著不允許重複,嘗試添加重複元素根本不會添加任何內容。
我們也可以對此進行測試,因為打印集合按插入順序打印其元素,並且在開頭和結尾添加重複元素只會導致第一個元素出現。
創建 Set
就像調用它的構造函數一樣簡單:
let mySet = new Set();
將元素添加到集合中
要將新元素添加到集合中,我們使用 add(value)
方法。
集合可以包含任意值。讓我們嘗試添加一些元素並故意添加重複項,看看 Set
是如何實現的 表現:
mySet.add(1);
mySet.add("one");
mySet.add("one");
mySet.add("two");
mySet.add(1);
console.log(mySet);
集合保持插入的順序,所以我們可以很容易地測試新的 1
覆蓋舊的 1
或者如果它的添加被簡單地跳過:
Set { 1, 'one', 'two' }
Set
識別相同的值元素,並且每個元素只保留一份副本。集合非常適合過濾掉重複值——你可以放入一堆應該是唯一的值,它們會被過濾掉。
不過,如果您不需要 Set
最後,最好過濾一個更合適的集合。
設置方法
Set 方法與 Map 方法非常相似,您可以輕鬆添加和刪除值以及檢查某些值是否屬於該集合,或者將其清除:
add(value)
- 為Set
添加一個新值 對象delete(value)
- 刪除傳遞的value
來自Set
對象has(value)
- 返回true
或false
取決於value
是否 在Set
對象clear()
- 刪除Set
中的所有值 對象
let mySet = new Set()
// Add values
mySet.add(1);
mySet.add("two");
// Delete a value
mySet.delete("two")
// Check if the deleted value is present
console.log(mySet.has("two")) // false
// Clear all values
mySet.clear()
// Check if first value is present
console.log(mySet.has(1)) // false
弱集對象
一個 WeakSet
object 是一個對象的集合 .與 Set
相同 的值,WeakSet
的對象必須是唯一的 .這指的是內存中的對象,而不是它們的字段或值。
Set
之間有一些關鍵區別 和一個 WeakSet
:
WeakSet
是一個對象的集合 ,而Set
是任何類型的值的集合。- 同
WeakMap
, 如果沒有對WeakSet
的引用 對象 - 它已被刪除。
HTML DOM 集合
這類集合是前端web開發相關的。
在處理網頁時,我們可以訪問頁面上的所有元素,這要歸功於 DOM 樹 .因此,當一次訪問多個元素時,它們將作為 HTMLCollection 返回 - 一個類似數組的 HTML 元素集合。
如果我們有一個網頁包含多個 <p>
標籤,我們可以用 document.getElementsByTagName("p")
檢索它們 - 返回所有 <p>
的集合 頁面上的元素:
let myHTMLCollection = document.getElementsByTagName("p");
console.log(myHTMLCollection[1]);
我們現在可以識別出 HTMLCollection
是一個“索引”集合,因為我們使用索引值訪問它的元素。這不是一個真實 索引 JavaScript 集合,因為它不是數組,因為它沒有數組方法,但是可以使用索引訪問。
一個 HTMLCollection
有 length
屬性,返回它的大小。
結論
根據您使用的數據,您將決定是使用索引集合還是鍵控集合。如果在網頁上工作,您可能會遇到 HTMLCollections。
快速回顧一下:
- 索引集合:
- 元素基於索引值 - 在 JavaScript 中從 0 開始。
Array
對象和TypedArray
對象。
- 鍵控集合:
- 元素基於鍵值對(類似於 JSON)。
Map
對象和Set
對象。
- HTML DOM 集合:
- 元素是 HTML 元素,基於索引值,同樣從 0 開始。