共计 5980 个字符,预计需要花费 15 分钟才能阅读完成。
前言
本文温习前端开发中常见的 3 种数据结构:数组 Array、有序集合 Set、有序映射 Map,并分别介绍其特性、用法示例
数组 -Array
适用于存放和读取有序集合、不要求集合元素唯一性时;可通过索引快速访问元素,实现元素增删改查时
使用方法
1. 创建、修改
let arr = [6,7,8,9,0];
console.log('len:',arr.length);
console.log('size:',arr.size)
console.log(arr.at(0));
console.log(arr[0]);
arr[0] = 100;
console.log(arr);
console.log(arr.fill(9999,2,4));
arr.fill(-1,0);
console.log(arr);
2. 添加删除元素
push 添加,pop 尾部删除,shift 头部删除,unshift 头部插入,concat 合并数组
let arr = [ 6, 7, 8, 9, 0 ]
let len = arr.push(10);
console.log("len:",len);
let lastVal = arr.pop();
console.log("lastVal:",lastVal,", len:",arr.length);
let delHeadVal = arr.shift();
console.log("delHeadVal:",delHeadVal,",len:",arr.length);
len = arr.unshift(88);
console.log("len:",len);
let arr2 = [2,4,6];
let ansArr = arr.concat(arr2);
console.log("ansArr len:",ansArr.length);
slice 拷贝数组元素
let nums = [1, 2, 3, 4, 5, 6, 7];
let sliceNums = nums.slice(1, 3);
console.log("sliceNums:", sliceNums);
sliceNums[0] = 888;
console.log("nums:", nums);
console.log(nums.slice(4));
console.log(nums.slice(5, -1));
console.log(nums.slice());
console.log(nums.slice(88));
splice 修改、删除、插入元素
let nums = [1, 2, 3, 4, 5, 6, 7];
let removedNums = nums.splice(2, 5);
console.log("removedNums:", removedNums, ", nums:", nums);
console.log("res:",nums.splice(1, 0, 'x', 'y', 'z'));
console.log("splice nums:", nums);
console.log("removed:", nums.splice(2), "nums:", nums);
nums = [1, 2, 3, 4];
console.log("del:", nums.splice(2, 1),", nums:",nums);
nums.splice(2, 1, 78, 88);
console.log("nums:", nums);
3. 筛选、查找元素
filter 筛选,find 查找元素,findIndex、indexOf、lastIndexOf 查找元素索引,includes 判断是否包含
let nums = [1, 2, 3, 4, 5, 6, 7];
let evenNums = nums.filter(x => x % 2 == 0);
console.log("evenNums:", evenNums);
let targetValue = nums.find(x => x > 5);
console.log("targetvalue:", targetValue);
let targetIndex = nums.findIndex(x => x > 5);
console.log("targetIndex:", targetIndex);
console.log("index:", nums.indexOf(5));
console.log(nums.indexOf(1, 5));
console.log(nums.lastIndexOf(5))
console.log(nums.includes(4));
console.log(nums.includes(2, 1));
4. 成分判断
every 测试所有都符合、some 测试至少一个元素符合
let nums = [5, 8, 4, 6, 7];
let isAllEven = nums.every(x => x % 2 == 0);
console.log("isAllEven:", isAllEven);
let hasEven = nums.some(x => x % 2 == 0);
console.log("hasEven:", hasEven);
5. 反转、排序
reverse 反转数组顺序,sort 排序
let ids = new Array(2, 0, 3, 5, 1, 4);
let reverseIds = ids.reverse();
console.log("reverseIds:", reverseIds);
console.log("ids:", ids);
console.log(ids.sort());
ids.sort((a,b)=>b-a);
console.log(ids);
6. 元素遍历
for…in 遍历索引,for…of 遍历元素,forEach 遍历元素及索引
let nums = [5, 8, 4, 6, 7];
for (let index in nums) {
console.log("index:", index, ", value:", nums[index]);
}
for (let x of nums) {
console.log("x=", x);
}
nums.forEach(x => {
console.log("x:", x);
});
nums.forEach((x, index) => {
console.log("x:", x, ", index:", index);
});
for (let i = 0; i nums.length; i++) {
console.log("nusm:", nums[i]);
}
7. 累计、分组运算
reduce 对数字元素进行算术累计运算,对字符串连接运算
let nums = [1, 2, 3];
let initVal = 0;
let sums = nums.reduce((preVal, curVal) => preVal + curVal, initVal);
console.log("sums:", sums);
const words = ['Hello', 'World', 'JavaScript'];
const sentence = words.reduce((accumulator, currentValue) => accumulator + '' + currentValue);
console.log("sentence:"+sentence);
let str = nums.join('-');
console.log(str);
reduce 分组
const users = [
{name:"User-A",age:21},
{name:'User-B',age:20},
{name:'User-C',age:20},
{name:'User-E',age:20}];
let initVal = {};
let ageGroup = users.reduce((preVal,curVal)=>{
let age = curVal.age;
if(!preVal[age]){
preVal[age] = [];
}
preVal[age].push(curVal);
return preVal;
},initVal);
console.log(ageGroup);
8. 变换
map、flatMap 将每个元素进行变换
let nums = [1, 2, 3];
console.log(nums.map(x=>'id-'+x));
let ans = nums.map(x=>[x*2]);
console.log(ans);
let ans2 = nums.flatMap(x=>[x*2]);
console.log(ans2);
let nums2 = nums.map(x=>[x,x*x]);
console.log(nums2);
let ans3 = nums.flatMap(x=>[x,x*x]);
console.log(ans3);
有序集合 -Set
用于存储具有唯一性的元素,常用于元素查找、去重场景
使用方法
1. 元素去重
普通类型插入元素唯一,可用于元素去重,对象插入是否唯一根据引用判断
let arr = [1,2,2,3,1];
let setNums = new Set(arr);
console.log(Array.from(setNums));
let set = new Set();
set.add(3);
set.add(2);
set.add(2);
console.log("size:", set.size);
2. 元素存在
可以在内部表示为哈希表,查找时间复杂度为 O(1)
let isContain = set.has(4);
console.log("isContain:", isContain);
3. 有序遍历
元素遍历时的顺序保持与插入顺序一致,可使用 forEach 或 for…of 遍历
let set = new Set([5,8,7,6]);
for (let id of set) {
console.log(id);
}
set.forEach(id => {
console.log("id:", id);
});
for (let value of set.values()) {
console.log("value:", value);
}
for (let [key, value] of set.entries()) {
console.log("key:", key, "value:", value);
}
4. 删除操作
delete 删除某个元素,clear 清空集合
let isDel = set.delete(5);
console.log("isDel:", isDel);
set.clear();
有序映射 -Map
Map 适合于频繁增删改键值对的场景,可确保的键唯一性,内部实现用的是哈希表,具有较好性能
使用方法
1. 键值添加、更改
新增或修改 set,取值 get,判断存在 has,删除 delete
let map = new Map();
map.set("name", "Alice");
map.set("age", 24);
map.set("name", "Blob");
console.log(map.has('name'));
console.log(Array.from(map.entries()));
let value = map.get("name");
console.log("value:", value);
console.log(map.size);
map.clear();
2. 有序遍历
Map 的键是有序的,遍历输出保持与添加时的顺序一致
Map 遍历 for…of 或 forEach
let userMap = new Map([['id', 23], ['name', 'zhangsan'], ['age', 18]]);
console.log(userMap);
for (const [key, value] of userMap) {
console.log("key:", key, ",value:", value);
}
for (const [key, value] of userMap.entries()) {
console.log("key#:", key, ",value#:", value);
}
for (let entry of userMap) {
console.log("entry:", entry);
}
userMap.forEach((value, key) => {
console.log("value=", value, ",key=", key);
});
for (const key of userMap.keys()) {
console.log("key:", key);
}
for (const value of userMap.values()) {
console.log('value:', value);
}
关于 Map 映射与普通 Object 对象的区别
1. 键的有序性:
Map
中的键以简单、直接的方式排序,Map
对象按照插入的顺序迭代条目、键和值
Object
的键排序比较复杂的,最好不要依赖属性的顺序
2. 键的类型:
Map 的键可以为任何值(包括函数、对象或任何原始值)
Object 的键必须为 String 或 Symbol
3. 大小计算:
Map
中的项目数量确定很容易从其 size 属性中获得
Object 中的项目数量确定比较麻烦,效率也较低,一种常见的方法是通过获取 Object.keys() 返回的数组的长度
4. 其他方面:
Map
性能在涉及频繁添加和删除键值对的场景中表现更好,而 Object
未针对频繁添加和删除键值对进行优化
关于普通 Object 用法
function testObject2() {
let obj = {};
obj[2] = 'zhangsan';
obj[1] = 'lisi';
console.log(obj);
obj.msg = "hello";
console.log(obj);
console.log(obj.hasOwnProperty("msg"));
console.log('msg' in obj);
for (let key in obj) {
console.log("key:", key, "value:", obj[key]);
}
Object.entries(obj).forEach((key, value) => {
console.log("key:", key, ", value:", value);
});
for (const [key, value] of Object.entries(obj)) {
console.log("key=", key, ", value=", value);
}
Object.keys(obj).forEach(key => {
console.log("key=", key);
});
delete obj.msg;
console.log(obj);
console.log(obj.msg);
console.log(Object.keys(obj).length);
}
参考资料
1.JavaScript 标准内置对象
2.JavaScript 数据类型
原文地址: javascript/js 中 Array、Set、Map 数据结构特性及用法