JavaScript 集合入门

Posted by cl9000 on August 12, 2021

介绍

不同形式的数据组是大多数编程语言中的基本数据结构之一。在许多情况下,通过不同数据类型表示的数据组被称为集合

在本指南中 - 我们将看看 JavaScript 中的集合以及何时使用哪种类型的集合。我们将研究的三个主要集合组是:

  • 索引集合
  • 键控集合
  • DOM 集合

索引集合

一个索引集是该数据的集合,通过它们的索引中。JavaScript 集合索引是从0开始的,这意味着它们从 开始0,而不是1一直到n-1,n即集合中对象的数量。JavaScript 有两种索引集合 ArraysTypedArrays

数组对象

Array JavaScript 中的对象是一个有序列表,可以使用索引访问其元素。ArrayJavaScript 中有多种创建对象的方法,并且在底层没有太大区别:

1
2
3
4
5
6
let myArray1 = [x1, x2, ... , xN];
let myArray2 = new Array(x1, x2, ... , xN);
let myArray3 = Array(x1, x2, ... , xN);

let myArray = ["one", 1, "two", 2];
// 0 1 2 3 --> index values

更改长度将更改数组

1
2
3
4
5
6
7
8
9
10
11
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 为比以前更大来扩展数组时,这正是发生的事情。

由于有三种方法可以创建一个充满元素的数组,因此也有三种方法可以创建具有分配内存的空数组,如下所示:

1
2
3
4
5
6
7
8
9
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

向数组添加元素

我们已经看到了如何创建一个 Array,无论是空的还是非空的。现在让我们看看如何向它添加新元素。由于我们正在使用索引集合,因此我们将使用索引进行操作。

由于我们已经创建了4个空元素,让我们使用它。要添加一个元素,我们所要做的就是通过它的索引访问该元素并为其分配一个值:

1
2
3
4
5
6
7
8
9
10
11
12
let myArray1 = new Array(4)

myArray1[0] = "one"
myArray1[1] = "two"
myArray1[2] = "three"
myArray1[3] = "four"

console.log(myArray)
// Output: ['one', 'two', 'three', 'four']
myArray1[4] = "five"
myArray1[5] = "six"
console.log(myArray) // Output: ['one', 'two', 'three', 'four', 'five', 'six']

我们可以使用 for 循环或 forEach 循环轻松地遍历数组

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
console.log('Traditional for loop:')
for (let i = 0; i < myArray1.length ; i++) {
trueconsole.log(myArray1[i]);
}

console.log('Functional forEach loop:')
myArray1.forEach( function (element){ console.log(element);});
// Output:
// Traditional for loop:
// one
// two
// three
// four
// five
// six

// Functional forEach loop:
// one
// two
// three
// four
// five
// six

数组方法

  • push() - 在数组末尾添加一个元素
1
2
3
let myArray = [1,2,3];
myArray.push(4);
console.log(myArray); // outputs [1, 2, 3, 4]
  • pop() - 删除数组的最后一个元素
1
2
3
let myArray = [1,2,3,4];
myArray.pop();
console.log(myArray); // outputs [1, 2, 3]
  • concat() - 将数组(两个或更多)连接到一个数组中
1
2
3
4
5
6
7
8
9
// 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
1
2
3
4
5
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() - 颠倒数组中元素的顺序
1
2
3
4
5
6
7
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和views。甲缓冲器是只存储数据的块的对象,没有方法来访问或操纵该数据。为了实现这一点,您必须使用视图——它提供了一个上下文,一种将数据转换为TypedArray.

甲缓冲通过一个实现ArrayBuffer对象。它用于表示固定长度的二进制数据缓冲区。为了表示这个缓冲区,我们必须创建一个视图DataView——它以选定的格式表示那个缓冲区。有多种类型的视图,代表最常见的数字类型:

  • Int8Array - 值范围 [-128, 127]
  • UInt8Array- 取值范围 [0, 255],u 代表无符号
  • Int16Array - 值范围 [-32768, 32767]
  • UInt16Array - 值范围 [0, 65535]
  • Float32Array - 数值范围 [1.2E-38, 3.4E38]

创建一个TypedArray

在创建 TypedArray某种类型的对象时,我们实现了我们之前所说的——创建缓冲区和视图。TypedArray对象没有显式构造函数——没有 new TypedArray()语法——我们直接实例化我们需要的数组类型:

1
2
3
4
5
6
let tArray = new Int8Array(8);
// 在这里,我们为 a 创建了一个缓冲区和一个Int8Array8 字节大小的视图。给元素赋值与Array对象相同:

tArray[0] = 10;
console.log(tArray);
// Int8Array [ 10, 0, 0, 0, 0, 0, 0, 0 ]

键控

一个键控集是在表示的数据的集合键值符号。元素的值通过它们各自的键来访问和操作。

JavaScript 中,有两种类型的键控集合:MapSet.

Map 对象

MapJavaScript 对象是含有一个标准的 Mqp 键-值对。要创建一个新Map对象,我们只需调用构造函数:

1
2
3
4
5
6
7
8
9
10
11
let myMap = new Map();

// 添加元素
myMap.set("one", 1);
myMap.set("two", 2);
myMap.set("three", "three");
console.log(myMap);

Map { 'one' => 1, 'two' => 2, 'three' => 'three' }
console.log(myMap.get("two")); // Output: 2
// get(key_name)在不存在的 key上调用该方法,则返回值也是undefined

Map方法

常用的方法:

  • set(key_name, value) - 将键值对添加到 Map.
  • get(key_name) - 返回分配给传递的键的值,如果没有这样的键 - 返回undefined
  • has(key_name) - 返回 truefalse 取决于 Map 是否有键key_name
1
2
console.log(myMap.has("two")); // true
console.log(myMap.has("five")) // false
  • delete(key_name) - 根据传递的键和值删除键和值 key_name ,如果传递的是不存在的键 - 没有任何反应:
1
2
3
4
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对象中删除每个键值对:
1
2
3
myMap.clear();
console.log(myMap);
// Output: Map {}

有一个主要的属性 Map——它的size属性。它包含一个表示 Map 对象大小的数值:

1
2
3
4
5
let myMap = new Map();
myMap.set("one", 1);
myMap.set("two", 2);
console.log(myMap.size);
// Output: 2

遍历 Map

MapJavaScript 中遍历对象有点 Python 风格。我们可以使用 for..of 语法来实现这一点:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
for (let [k, v] of myMap){	
console.log(k + " written in number is " + v)
}
// 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

WeakMap对象

WeakMapMapAPI 相同

1
2
3
4
5
6
7
let myMap = new WeakMap();

let athlete = class Athlete{}
myMap.set(athlete, 1);

console.log(myMap.get(athlete))
// 1

集合对象 Set

一个 SetJavaScript 对象仅仅是值的集合。这些值是唯一的,这意味着不允许重复,并且尝试添加重复元素不会添加任何内容。

我们也可以测试这一点,因为打印集按插入顺序打印它们的元素,并且在开始和结束添加重复元素只会导致第一个出现。

创建 Set就像调用它的构造函数一样简单:

1
2
3
4
5
6
7
8
9
let mySet = new Set();

// 向集合添加新元素,使用add(value)方法。
mySet.add(1);
mySet.add("one");
mySet.add("one");
mySet.add("two");
mySet.add(1);
console.log(mySet);

集合保持插入的顺序,所以我们可以很容易地测试新的是否1覆盖旧的1或者它的添加是否被简单地跳过:

1
Set { 1, 'one', 'two' }

Set方法

  • add(value) - 为Set对象添加一个新值
  • delete(value) - 删除 valueSet对象
  • has(value) - 返回truefalse取决于value是否在Set对象中
  • clear() - 从Set对象中删除所有值
1
2
3
4
5
6
7
8
9
10
11
12
13
14
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

一个WeakSet对象是一个对象的集合。与Set的值相同,WeakSet的对象必须是唯一的。这是指内存中的对象,而不是它们的字段或值。

SetWeakSet之间有一些主要区别:

  • WeakSetobjects 的集合,而 Set 是任何类型的值的集合。
  • WeakMap 相同,如果没有对 WeakSet对象的引用- 它被删除。

参考

关注【公众号】,了解更多。



支付宝打赏 微信打赏

赞赏一下 坚持原创技术分享,您的支持将鼓励我继续创作!