数据结构上篇
Posted jrzqdlgdx
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了数据结构上篇相关的知识,希望对你有一定的参考价值。
第4章数据结构
所谓数据结构,就是计算机存储和组织数据的方式。说得通俗一点,主要就是指将数据以什么样 的结构存储到计算机里面。在程序里面,最为常见的数据结构,就是数组,这种结构将多个数据 有序的排列在一起,形成了一个组合。除了数组以外,集合,映射等ES6新增加的数据结构,也 会在本章中向大家详细介绍。
本章中我们将学习如下的内容:
?数组基础知识
?数组相关属性和方法
?集合
?映射
4-1数组基础
数组是大多数语言里面最常见的一种数据结构,它是一个有序的值列表。
4-1-1创建数组
创建数组的方式大致可以分为两种:字面量创建数组和使用构造函数创建数组。示例如下:
- 字面量创建数组
let arr = [];
- 构造函数创建数组
let arr = new Array();
需要注意的是,无论是字面量形式创建的数组,还是构造函数创建的数组,当我们使
用typeof来打印其数据类型的时候,都会返回一个object,如下:
let arr1 = [];
let arr2 = new Array();
console.log(typeof arr1);//object
4-1-2数组赋值
给数组赋值的方法也非常简单,不过可以分为先声明再赋值和声明时直接赋值,如下:
- 先声明再赋值
let arr = [];
arr[0] = 1;
arr[1] = 2;
arr[2] = 3;
注意下标是从o开始的。
- 声明时直接赋值
let arr = [1,2,3,4,5];
需要注意的是我们可以在数组的任意位置进行赋值,数组的长度会自动改变,空的位置使用
undefined来进行填充
let arr = [];
arr[0] = 1;
arr[4] = 10;
console.log(arr);
//[ 1, <3 empty items>, 10 ]
由于JS是动态语言,所以JS里面数组的数据类型可以是任意类型
let arr = [1,"Hello",3.14,true];
4-1-3访问数组元素
通过数组的下标,我们可以轻松的访问到存储在数组里面的元素,如下:
let arr = [1,2,3,4,5];
console.log(arr[0]);//1
需要注意数组里面的第一个元素是从下标0开始的。
除了这种常规的访问方式,我们还可以使用变量的方式来进行访问,如下:
let arr = [1,2,3,4,5];
let i = 2;
console.log(arr[i]);//3
4-1-4删除元素
我们可以使用delete运算符来删除数组中的某一个元素,示例如下:
let arr = [1,2,3,4,5];
delete arr [2]; //删除数组中的第3个元素 console.log(arr);
//[ 1, 2, <1 empty item>, 4, 5 ]
4-1-5数组的遍历
接下来我们来看一下数组的遍历,在javascript中,遍历数组的方式非常的多。这里先介绍几种 常见的数组遍历方式。
通过for循环来遍历数组
最简单的方式就是通过for循环来进行数组的遍历,这也是一直以来被使用得最多的方式,示例如 下:
let arr = [1, 2, 3, 4, 5];
for (let i=0;i<arr.length;i++) console.log(arr[i]);
// 1
// 2
// 3
// 4
// 5 通过for-in来遍历数组
for-in主要迭代的是数组的键,然后我们通过键就可以找到相应的数组元素,示例如下:
let arr = [1, 2, 3, 4, 5]; for (let i in arr)
console.log(‘ 键为 $ i的元素值为 $a rr[ i]‘);
//键为0的元素值为1
//键为1的元素值为2
//键为2的元素值为3
//键为3的元素值为4
//键为4的元素值为5
通过for-o f来遍历数组
上面介绍的for-in是迭代数组的键,这里所介绍的for-of是直接迭代数组的值,示例如下:
let arr = [1, 2, 3, 4, 5];
for (let i of arr) console.log(i);
// 1
// 2
// 3
// 4
// 5
通过forEach来遍历数组(扩展)
最后再介绍一种通过for Each的方式来遍历数组,不过这里涉及到了回调函数的知识。在第5章 我们就会学习回调函数,所以这里大家先了解一下这种遍历的方式即可,示例如下:
let arr = [1,2,3,4,5,6,7,8,9,10];
//将数组的每一项传入到回调函数,然后执行回调函数里面的操作
let i = arr.forEach(function(item)
console.log(item);
);
使用迭代器进行遍历
在ES6中,还专门提供了 3个用于迭代可迭代元素的方法,分别是keys() , values()以 及ent ries()方法。其中keys()是找到可迭代元素的键,values()是找到可迭代元素的 值,ent ri es()是同时找到可迭代元素的键和值。
注意:数组里面无法使用values()方法
示例:使用keys()遍历出数组的键
let arr = [3,5,8,1];
for(let i of arr.keys()) console.log(i);
// 0
// 1
// 2
// 3
示例:使用ent ries()方法遍历出数组的键和值
let arr = [3,5,8,1];
for(let i of arr.entries())
|
console.log(i); |
|
|
|
|
// |
[ 0, 3 |
] |
// |
[ 1, 5 |
] |
// |
[ 2, 8 |
] |
// |
[ 3, 1 |
] |
4-1-6解构数组
首先我们需要了解什么是解构,所谓解构,就是将一个复杂类型的数据分解为一个普通类型数 据。解构是从ES6开始新添加的功能。可以对数组和对象进行解构。这里我们先来看一下数组的 解构,如下:
let arr = [1,2,3]; let [a,b,c] = arr; console.log(a);//1 console.log(b);//2 console.log(c);//3
这里,就是将arr这个数组里面的值分解给了 a,b,c
可以使用逗号来跳过不想要解构的元素,如下:
let arr = [1,2,3]; let [a,,b] = arr; console.log(a);//1 console.log(b);//3
在解构出现之前,我们交换两个数需要使用到一个中间变量,但是现在我们可以使用解构来交换 两个数
let a = 1,b = 2;
[a,b] = [b,a];
console.log(a);//2
console.log(b);//1
关于对象的解构,我们会在后面进行介绍,详细参见对象的相关章节。
4-1-7多维数组
首先需要说明的是,JS里面不支持传统编程语言中的多维数组。但是,由于JS的数组里面所存 放的数据的数据类型可以是任意类型,所以我们可以模拟出多维数组
let a = ["Bill","Mary","Lucy"];
let b = [21,24,27];
let c = [a,b]; //这里c就是一个多维数组
如果要访问多维数组里面的数据,可以使用下面的形式
let a = ["Bill","Mary","Lucy"];
let b = [21,24,27];
let c = [a,b];
console.log(c[0][2]); //Lucy
利用前面所介绍的解构,我们可以来解构一个多维数组,示例如下:
let arr = [[1,2,3],4,5];
let [a,b,c] = arr;
console.log(a); //[1,2,3]
console.log(b); //4
console.log(c); //5
4-1-8扩展运算符
扩展运算符是ES6开始新添加的运算符,用于取出可迭代对象的每一项。这里我们可以用它来快 速的展开一个数组
let a = ["Bill","Mary","Lucy"]; let b = [21,24,27];
let c = [...a,...b]; console.log(c);
//[ ‘Bill‘, ‘Mary‘, ‘Lucy‘, 21, 24, 27 ]
我们再来看一个例子:
let a = [1,2,3];
let b = [...a,4,5,6]; console.log(b);
//[ 1, 2, 3, 4, 5, 6 ]
有了这个运算符以后,我们可以使用它将字符串快速转为数组
let str = "Hello";
let arr = [...str]; console.log(arr);
//[ ‘H‘, ‘e‘, ‘l‘, ‘l‘, ‘o‘ ]
4-2数组属性和方法
4-2-1数组相关属性
length:返回数组元素的个数
let arr = [1,2,3,4,5]; console.log(arr.length);//5
我们利用此属性,可以快速的清空数组,这种方法比使用重新赋值的效率要高些,如下:
let arr = [1,2,3,4,5];
arr.length = 0; console.log(arr);//[]
其实我们使用length属性就是可以随意的对数组的长度进行操控
let arr = [1,2,3,4,5];
arr.length = 3;
console.log(arr);//[1,2,3]
4-2-2数组相关方法
1.添加删除方法
数组可以表现得像栈一样。
栈是一种LIFO(Last-ln-First-Out)数据结构,这种数据结构的特点是后进先出。 ECMAScript中专门提供了 push。和pop。方法,用来实现类似栈的行为。
let arr = [];
let i = arr.push("red","blue"); console.log(arr);//[ ‘red‘, ‘blue‘ ] console.log(i);//2
let j = arr.pop(); console.log(arr);//[ ‘red‘ ] console.log(j);//blue
注意push。方法推入元素的时候是从右往左边推入的,如下:
let arr = [];
arr.push("red","blue","pink"); console.log(arr);
//只有一个入口
//
//| red blue pink
//
队列方法的特点是先进先出FIFO(First-ln-First-Out),因为有两个出口。
在ECMAScript中提供了 shift。方法,该方法可以去除数组中第一个元素并且返回该元素。 利用shift。和push。方法就可以实现从右往左的队列
//从右往左的队列
let arr = []; arr.push("red","green","pink");
let item = arr.shift(); console.log(item);//red console.log(arr);//[ ‘green‘, ‘pink‘ ]
如果要实现从左往右的队列,可以使用unshiftO方法和pop。方法的配合。unshiftO方法的作用是 在数组开头推入一个元素
//从左往右的队列
let arr = []; arr.unshift("red","green","pink");
let item = arr.pop();
console.log(item);//pink
console.log(arr);//[ ‘red‘, ‘green‘ ]
push。和pop。可以算是一组方法,作用分别是在数组尾部推入和弹出元素。 unshiftO和shift。可以算是一组方法,作用分别是在数组头部推入和弹出元素。 推入的时候可以一次性推入多个元素,返回的是新数组的长度。
弹出的时候一次只能弹出一个元素,返回的是弹出的那个元素
2.操作方法
操作方法里面介绍3个操作方法,分别是concatO, slice。和splice。
concatO:该方法是先创建当前数组的一个副本,然后将接收到的参数添加到副本的末尾,最后 返回新构建的数组,而原本的数组不会变化。
let arr = [1,2,3];
let arr2 = arr.concat("red","blue");
console.log(arr);//[ 1, 2, 3 ] console.log(arr2);//[ 1, 2, 3, ‘red‘, ‘blue‘ ]
slice。:该方法可以接收一个或者两个参数,代表返回项的起始和结束位置。
—个参数:那就代表起始位置,返回从指定的起始位置到数组末尾的所有项目
两个参数:那就代表从指定的起始位置到指定的末尾位置之间的项,但是不包括结束位置的项 目。
注意:slice。方法不会影响原始数组
let arr = [1,2,3,4,5,6,7,8,9,10];
//—个参数
let i = arr.slice(3);
console.log(i);//[ 4, 5, 6, 7, 8, 9, 10 ]
console.log(arr);//[ 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 ]
//两个参数
let j = arr.slice(2,6);
console.log(j);//[ 3, 4, 5, 6 ] console.log(arr);//[ 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 ]
如果传入的是负数,则用数组长度加上该数来确定相应的位置
let arr = [1,2,3,4,5,6,7,8,9,10];
// —个参数
let i = arr .slice(-3);//等价于slice(7)
console.log(i);//[ 8, 9, 10 ]
//两个参数
let j = arr .slice(-6,-2);//等份于slice(4,8)
console.log(j);//[ 5, 6, 7, 8 ]
//不满足条件返回空数组
let k = arr .slice(-2,-6);//等份于slice(8,4)
console.log(k);//[]
spliceO:这个方法非常的厉害,可以实现对数组的3种类型的操作:删除,插入和替换,相当于 是增删改操作都可以用这个方法来实现。
删除:可以删除任意数量的元素,只需要指定2个参数:要参数的第一项位置和要删除的项数。
let arr = [1,2,3,4,5,6,7,8,9,10];
//从下标为3的元素开始删除,删除5个元素
//将删除的元素返回给i
let i = arr.splice(3,5); console.log(i);//[ 4, 5, 6, 7, 8 ] console.log(arr);//[ 1, 2, 3, 9, 10 ]
插入:可以向任意位置插入任意数量的元素。只需要提供3个参数:起始位置,0(要删除的项 目),要插入的项目。
let arr = [1,2,3,4,5,6,7,8,9,10];
//从下标为3的元素之前开始插入
let i = arr.splice(3,0,"red","blue");
console.log(i);//[]
console.log(arr);
//[ 1, 2, 3, ‘red‘, ‘blue‘, 4, 5, 6, 7, 8, 9, 10 ]
替换:替换的原理在于插入的时候同时进行删除,这样就实现了替换功能
let arr = [1,2,3,4,5,6,7,8,9,10];
//从下标为3的元素之前开始插入
//插入多少,刚好就删除多少
let i = arr.splice(3,2,"red","blue"); console.log(i);//[ 4, 5 ] console.log(arr);
//[ 1, 2, 3, ‘red‘, ‘blue‘, 6, 7, 8, 9, 10 ]
数组和字符串相互转换:join。和split。
join。:将数组转为字符串,可以传入分隔符作为参数
let arr = [1,2,3];
let str = arr.join(""); console.log(str);//123 let str2 = arr.join(","); console.log(str2);//1,2,3
split。:将字符串转为数组,传入参数指明以什么作为分隔符
let str = "Hello";
let arr = str.split("");
console.log(arr);//[ ‘H‘, ‘e‘, ‘l‘, ‘l‘, ‘o‘ ]
let arr2 = str.split("l"); console.log(arr2);//[ ‘He‘, ‘‘, ‘o‘ ]
- 数组重排序方法
重排序涉及到两个方法:reverse。和sort。
reverse。:反转数组项的顺序,注意使用该方法时会改变原来数组的顺序,而不是返回一个副本
let arr = [1,2,3,4,5]; console.log(arr.reverse());//[ 5, 4, 3, 2, 1 ] console.log(arr);//[ 5, 4, 3, 2, 1 ]
sortO:按照升序排列数组每一项
let arr = [0,12,3,7,-12,23];
console.log(arr.sort());
//[ -12, 0, 12, 23, 3, 7 ]
可以看到,我们调用sort。方法以后排序并没有正确的按照升序来进行排序。
原因在于:sort()方法排序时首先会调用每个元素的toStringO转型方法,然后比较得到的字符串。 即使每一项都是数值,sort()方法比较的也是字符串。
解决方法:sort()方法可以接收一个比较函数作为参数,以便我们指定哪个值位于哪个值的前面。 比较函数接收两个参数,如果第一个参数应该位于第二个数的前面,返回一个负数,如果两个参 数相等,返回0,如果第一个参数应该位于第二个数的后面,返回一个正数。
let arr = [0,12,3,7,-12,23];
console.log(arr.sort(function(a,b)
if(a < b)
return -1;
else if(a > b)
return 1;
else
return 0;
));
如果是要进行降序排列,只需要将返回值进行修改即可
let arr = [0,12,3,7,-12,23];
console.log(arr.sort(function(a,b)
if(a < b) return 1;
else if(a > b)
return -1;
else
return 0;
));
事实上我们的比较函数还有一种更加简单的书写方法,如下:
let arr = [0,12,3,7,-12,23]; console.log(arr.sort(function(a,b) return a - b;
//降序就返回b - a
));
最后需要注意的是,reverse。和sort。方法,返回值是经过排序之后的数组
- 位置方法
ECMAScript还为数组提供了两个位置方法:indexOf。和lastlndexOf。
这两个方法都接收两个参数:要查找的项目和查找的起点位置索引。区别在于一个是从数组开头
开始找,一个是从数组末尾开始找。如果没找到就返回-1
let arr = ["H","e","l","l","o"];
console.log(arr.indexOf("l"));//2 console.log(arr.lastIndexOf("l"));//3 console.log(arr.indexOf("z"));//-1
还需要注意的是,这两个方法进行查找时使用的是全等进行比较
let arr = ["1","2","3"];
console.log(arr.indexOf(1));//-1
includes。:用于查看数组里面是否包含某个元素,包含返回true,否则返回false
let arr = ["1","2","3"]; console.log(arr.includes(2));//flase console.log(arr.includes("2"));//true console.log(arr.includes(7));//false
以上是关于数据结构上篇的主要内容,如果未能解决你的问题,请参考以下文章