数据结构 Set 与 Array
数据结构 Set 与 Array
一、Set 与 Array 是什么
-
Set 是 ES6 提供的一种新的数据结构。Set 中的元素只会出现一次,即 Set 中的元素是唯一的。Set 是值的集合,是无序的。
-
Array 中的元素可以是原始类型或对象类型。Array 是有序数据的集合。
二、Set 的用途
Set 类似于 Array,同 Array 方法中有相似之处。Set 的一个特性是,没有相同的成员(完全相等的成员)。
-
所以在不需要有重复元素的情况下,可以用 Set 数据结构来替代 Array。
-
同时,因为这一特性,可以用 Set 数据结构来转换没有重复的数组。
三、生成 Set 和 Array 数据结构
- Set 数据结构使用构造函数 Set 来生成。
const s = new Set();
console.log(s) // Set []
- Array 数组也可以用 Array 构造函数来生成.
const arr = new Array();
console.log(arr) // Array[]
四、Set 与 Array 对比
属性对比
- 获取数据结构元素个数
- Set 数据结构通过 size 来获取成员的数量。无法改变 size 的值。
const s = new Set();
s.add(1).add(2);
console.log(s.size); // 2
s.size = 3; // 3
console.log(s.size); // 2, size 值不可以改变
- Array 数组通过 length 来获取成员的数量。length 的值可以改变。
const arr1 = new Array(2);
console.log(arr1.length) // 2(如果用 Array 构造函数创建的数组,其值只有一个,且该值为数字,则该值表示的是该数组的长度)
console.log(arr1) // [empty × 2]
const arr2 = new Array(1, 2, 3);
console.log(arr2.length) // 3
arr2.length = 2;
console.log(arr2.length); // 2,lenght 值可以改变
方法对比
- 添加元素
- Set 数据结构通过 add() 方法在末尾添加一个指定的值,返回对象本身。不能添加重复的值。
const s = new Set();
console.log(s) // Set []
s.add(1);
console.log(s) // Set [ 1 ]
s.add(2).add('hello'); // 可以链式调用
console.log(s) // Set(3) [ 1, 2, 'hello' ]
s.add(2); // 试图添加一个重复的值 2
console.log(s) // Set(3) [ 1, 2, 'hello' ]
- Array 数组通过 push() 方法将一个或多个元素添加到数组的末尾,并返回该数组的新长度。
const animals = ['pigs', 'goats', 'sheep'];
const count = animals.push('cows');
console.log(count) // 4
console.log(animals) // Array ["pigs", "goats", "sheep", "cows"]
- Array 数组通过 unshift() 方法将一个或多个元素添加到数组的开头,并返回该数组的新长度(该方法修改原有数组)。
const arr1 = [1, 2, 3];
console.log(arr1.unshift(4, 5)); // 5
console.log(arr1); // Array [4, 5, 1, 2, 3]
- Array 数组通过 splice() 方法通过删除或替换现有元素或者原地添加新的元素来修改数组,并以数组形式返回被修改的内容(此方法会改变原数组)。
const months = ['Jan', 'March', 'April', 'June'];
months.splice(1, 0, 'Feb'); // 在索引为 1 的位置删除 0 个元素,添加 'Feb' 元素
console.log(months); // Array ["Jan", "Feb", "March", "April", "June"]
- 删除元素
- Set 数据结构通过 delete() 方法删除指定的元素(成功删除返回 true,否则返回 false)。
const s9 = new Set();
s9.add(1).add(2).add(3); // Set(3) [ 1, 2, 3 ]
s9.delete(4) // false
s9.delete(3) // true
- Array 数组通过 pop()方法从数组中删除最后一个元素,并返回该元素的值(此方法更改数组的长度)。
const team = ["前端产品组", "前端产品组", "前端产品组", "军工算法组"];
const popped = team.pop();
console.log(team) // ["前端产品组", "前端产品组", "前端产品组"]
console.log(popped) // "军工算法组"
- Array 数组通过 shift() 方法从数组中删除第一个元素,并返回该元素的值(此方法更改数组的长度)。
const fruits = ['banana', 'apple', 'orange'];
const shifted = fruits.shift();
console.log(shifted) // "banana"
console.log(fruits) // Array ["apple", "orange"]
- Array 数组通过 splice() 方法通过删除或替换现有元素或者原地添加新的元素来修改数组,并以数组形式返回被修改的内容(此方法会改变原数组)。
const years = ['1919', '2008', '2018', '2020'];
const spliced = years.splice(1, 1); // 在索引为 1 的位置删除 1 个元素
console.log(spliced); // "2008"
console.log(years); // Array ["1919", "2018", "2020"]
- 清空元素
- Set 数据结构通过 clear() 方法清空元素成员。返回值 undefined。
let s = new Set();
s.add(1);
s.add("foo");
s.size; // 2
s.has("foo"); // true
s.clear();
s.size; // 0
s.has("bar") // false
- Array 数组通过将 length 属性设置为 0,来清空数组。
let arr = new Array(4, 5, 6);
arr.length = 0;
console.log(arr); // Array []
console.log(arr.length); // 0
- Array 数组通过将值设置为空数组,来清空数组。
let arr = new Array(4, 5, 6);
arr = [];
console.log(arr); // Array []
console.log(arr.length); // 0
- 判断元素是否存在
- Set 数据结构通过 has() 来指示对应的值 value 是否存在 Set 对象中。如果指定的值 value 存在于 Set 对象当中,返回 true;否则返回 false。
const s = new Set();
s.add('foo');
console.log(s.has('foo')); // true
console.log(s.has('bar')); // false
- Array 数组通过 includes() 方法用来判断一个数组是否包含一个指定的值,根据情况,如果包含则返回 true,否则返回 false。
const pets = ['cat', 'dog'];
console.log(pets.includes('cat')); // true
console.log(pets.includes('pig')); // false
- Array 数组通过 indexOf() 方法返回在数组中可以找到一个给定元素的第一个索引。如果不存在,则返回 -1,如果存在则返回索引。
const beasts = ['ant', 'camel', 'duck', 'ant'];
console.log(beasts.indexOf('ant')); // 0
console.log(beasts.indexOf('ant', 2)); // 3
console.log(beasts.indexOf('dog')); // -1
- 迭代元素
- Set 可以使用 forEach() 遍历成员。
let s = new Set([1, 4, 9]);
s.forEach((value, key) => console.log(key + ' : ' + value))
// 1 : 1
// 4 : 4
// 9 : 9
第一个参数是处理函数,该函数的参数依次是 “健值,健名,集合本身”。Set 结构的健值就是健名,所以第一个参数和第二个参数永远相同。
- Array 也可以使用 forEach() 遍历成员。
let arr = new Array(1, 4, 9);
arr.forEach((value, index) => console.log(index + ' : ' + value));
// 0 : 1
// 1 : 4
// 2 : 9
与 Set 数据结构不同的是,Array 数组的健名是从 0 开始的有序整数。也称为索引。
- Set 数据结构还包含 keys(), values(), entries() 方法来遍历健名、健值、健值对。返回对应的遍历器。通过 for of 来遍历遍历器。
let set = new Set(['red', 'green', 'blue']);
for (let item of set.keys()) {
console.log(item);
}
// red
// green
// blue
let set = new Set(['red', 'green', 'blue']);
for (let item of set.values()) {
console.log(item);
}
// red
// green
// blue
let set = new Set(['red', 'green', 'blue']);
for (let item of set.entries()) {
console.log(item);
}
// Array [ "red", "red" ]
// Array [ "green", "green" ]
// Array [ "blue", "blue" ]
五、Set 与 Array 转换
- Set 转 Array
Array.from() 方法可以将 Set 数据结转为数组。
const setItems = new Set([1, 2, 3, 4, 5]);
const arrayItems = Array.from(setItems);
console.log(setItems); // Set(5) [ 1, 2, 3, 4, 5 ]
console.log(arrayItems); // Array(5) [ 1, 2, 3, 4, 5 ]
因为 Set 可迭代,也即 Set 具有 Iterator 接口。所以使用扩展运算符 ... 也可以将 Set 数据结构转换成 Array。
const setItems = new Set([1, 2, 3, 4, 5]);
const arrayItems = [...setItems];
console.log(setItems); // Set(5) [ 1, 2, 3, 4, 5 ]
console.log(arrayItems); // Array(5) [ 1, 2, 3, 4, 5 ]
- Array 转 Set
Set 构造函数可以接受一个数组作为参数,用来初始化。实现 Array 转 Set。
const srrayItems = ['hello', 'world'];
const setItems = new Set(srrayItems);
console.log(srrayItems); // Array [ "hello", "world" ]
console.log(setItems); // Set [ "hello", "world" ]
六、数组去重
因为 Set 数据结构无法添加重复的元素,所以 Set 构造函数很适合用来去除数组中重复的的元素。
- 先使用 Set 构造函数,去除数组中重复的元素;再使用扩展运算符 ... 转换为数组。
[...new Set([1, 2, 3, 3, 2])]; // Array [ 1, 2, 3 ]
同理,字符串可以用类似的方法去重。
[...new Set('ababbc')].join(''); // "abc"
- 另一种去重方法是先使用 Set 构造函数,去除数组中重复的元素;再使用扩展运算符 Array.from() 方法转换为数组。
Array.from(new Set([1, 2, 3, 3, 2])); // Array [ 1, 2, 3 ]
欢迎写出你的看法,一起成长!