JS集合-Array
Array
EcmaScript 数组也是有序数组,跟其他语言不同的是,数组中的每个槽位可以存储任何类型的数据。意味着可以创建一个数组,它的第一个元素是字符串,第二个元素是数值,第三个是对象。数组是动态大小的,随着数据添加而自动增长。
1.创建数组
一种使用Array构造函数;
let colors = new Array();
let colors=new Array(3);
let colors = new Array("red", "blue", "green");
另一种是使用数组字面量创建数组,在使用数组字面量表示法创建数组不会调用 Array 构造函数。
let colors=["red", "blue", "green"];
let colors=[]; //空数组
let values = [1,2,]; //创建包含两个元素的数组
第3中Array构造函数还有两个 ES6 新增的用于创建数组的静态方法:from()和 of()
Array.from()的第一个参数是一个类数组对象,即任何可迭代的结构,或者有一个 length 属性和可索引元素的结构。
// 字符串会被拆分为单字符数组
console.log(Array.from("Matt")); // ["M", "a", "t", "t"]
// 可以使用 from()将集合和映射转换为一个新数组
const m = new Map().set(1, 2)
.set(3, 4);
const s = new Set().add(1)
.add(2)
.add(3)
.add(4);
console.log(Array.from(m)); // [[1, 2], [3, 4]]
console.log(Array.from(s)); // [1, 2, 3, 4]
// Array.from()对现有数组执行浅复制
const a1 = [1, 2, 3, 4];
const a2 = Array.from(a1);
console.log(a1); // [1, 2, 3, 4]
alert(a1 === a2); // false
// 可以使用任何可迭代对象
const iter = {
*[Symbol.iterator]() {
yield 1;
yield 2;
yield 3;
yield 4;
}
};
console.log(Array.from(iter)); // [1, 2, 3, 4]
Array.from()还接收第二个可选的映射函数参数。这个函数可以直接增强新数组的值,而无须像调用 Array.from().map()那样先创建一个中间数组。还可以接收第三个可选参数,用于指定映射函数中this 的值。但这个重写的 this 值在箭头函数中不适用。
const a1 = [1, 2, 3, 4];
const a2 = Array.from(a1, x => x**2);
const a3 = Array.from(a1, function(x) {return x**this.exponent}, {exponent: 2});
console.log(a2); // [1, 4, 9, 16]
console.log(a3); // [1, 4, 9, 16]
Array.of() 可以把一组参数转换成数组。
console.log(Array.of(1, 2, 3, 4)); // [1, 2, 3, 4]
console.log(Array.of(undefined)); // [undefined]
2.数组空位
使用数组字面量初始化数组时,会使用一串逗号来创建空位。ECMAScript 会将逗号之间相应索引位置的值当成空位。ES6中将空位视为undefined.
const options = [,,,,,]; // 创建包含 5 个元素的数组
建议:如果确定要使用数组空位,建议显式的用undefined值代替。
3.数组索引
要取得或者设置数组的值,可以通过索引
let colors = ["red", "blue", "green"]; // 定义一个字符串数组
alert(colors[0]); // 显示第一项
colors[2] = "black"; // 修改第三项
colors[3] = "brown"; // 添加第四项
数组的length属性可以修改,通过修改length属性,可以删除或新增数组数据。
//修改length属性删除数组数据
let colors=["red","blue","green"]
colors.length=2 // 修改length属性,删除数组数据
console.log(colors) //red,blue
//修改length属性,如果将 length 设置为大于数组元素数的值,则新添加的元素都将以undefined 填充,
let colors=["red","blue","green"]
colors.length=4
console.log(colors[3]) // undefined
4.检测数组
检测一个对象是不是数组,可以通过Array.isArray() 方法。
5.迭代器方法
ES6 中,Array原型暴露3个检索数组的方法keys(), values(), entries()。
keys(): 返回数组索引迭代器;
values(): 返回数组元素的迭代器;
entries():返回索引/值的迭代器;
const a = ["foo", "bar", "baz", "qux"];
// 因为这些方法都返回迭代器,所以可以将它们的内容
// 通过 Array.from()直接转换为数组实例
const aKeys = Array.from(a.keys());
const aValues = Array.from(a.values());
const aEntries = Array.from(a.entries());
console.log(aKeys); // [0, 1, 2, 3]
console.log(aValues); // ["foo", "bar", "baz", "qux"]
console.log(aEntries); // [[0, "foo"], [1, "bar"], [2, "baz"], [3, "qux"]]
6.复制和填充数组
填充数组:用 fill()方法可以向一个已有的数组中插入全部或部分相同的值;
fill(一个参数): 用该参数填充数组所有元素;
fill(参数A,起始索引B): 从B位置开始填充数组元素为A;
fill(参数A,起始索引B,结束索引C) : 从数组索引B开始填充元素为A,直到索引C结束;
fill() 如果索引的索引位置超出数组索引范围,则不执行填充操作。
const zeroes=[0,0,0,0,0]
//使用5填充整个数组
zeroes.fill(5)
console.log(zeroes) //[5,5,5,5,5]
zeroes.fill(0)
//用6填充索引大于等于3元素
zeroes.fill(6,3)
colose.log(zeroes) //[0,0,0,6,6]
zeroes.fill(0)
//用7填充索引大于等于1且小于3的元素
zeroes.fill(7,1,3)
console.log(zeroes) //[0,7,7,0,0]
zeroes.fill(0)
// 用 8 填充索引大于等于 1 且小于 4 的元素
// (-4 + zeroes.length = 1)
// (-1 + zeroes.length = 4)
zeroes.fill(8, -4, -1);
console.log(zeroes); // [0, 8, 8, 8, 0];
//索引超过数组范围,静默
zeroes.fill(1, -10, -6);
console.log(zeroes); // [0, 0, 0, 0, 0]
复制数组:copyWithin()
copyWithin() 会按照指定范围内浅复制数组中的部分内容,然后把它们插入到指定索引开始的位置。
let ints,
reset = () => ints = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9];
reset();
1. 从ints中复制索引0开始的内容,插入到索引5的位置
// 在源索引或目标索引到达数组边界时停止
ints.copyWithin(5);
console.log(ints); // [0, 1, 2, 3, 4, 0, 1, 2, 3, 4]
reset();
2.从ints 中复制索引5开始的内容,并插入到索引0的位置
ints.copyWithin(0,5)
console.log(ints); // [5, 6, 7, 8, 9, 5, 6, 7, 8, 9]
reset()
3.从ints中复制从索引0开始到索引3结束的内容,插入到索引4的位置
ints.copyWithinf(4,0,3)
console.log(ints) // [0, 1, 2, 3, 0, 1, 2, 7, 8, 9]
4.支持负索引
ints.copyWithin(-4, -7, -3);
alert(ints); // [0, 1, 2, 3, 4, 5, 3, 4, 5, 6]
5. 索引超出数组范围,静默
ints.copyWithin(1, -15, -12);
alert(ints); // [0, 1, 2, 3, 4, 5, 6, 7, 8, 9];
reset()
7.栈方法
栈是先进后出的特殊线行表结构,存储上分链式存储和顺序存储两种方式。
数据的出栈和进栈只在栈的一个地方发生,即栈顶。
入栈:push(...) ,push()接受任意数量的参数,并将它们添加数组末尾(即栈顶),并返回数组的最新长度。
出栈:pop(), 用于删除数组的最后一项,并返回被删除的项。
let colors = new Array(); // 创建一个数组
let count = colors.push("red", "green"); // 推入两项
alert(count); // 2
count = colors.push("black"); // 再推入一项
alert(count); // 3
let item = colors.pop(); // 取得最后一项
alert(item); // black
alert(colors.length); // 2
8.队列方法
队列是一种特殊的线性表,特殊之处在于它只允许在表的前端(front)进行删除操作,在表的后端(rear)进行插入操作,和栈一样,队列是一种操作受限制的线性表, 队列在列表末尾添加数据,在列表开头获取数据。
列表开头获取数据:shift(), 该方法会删除数组的第一项,并返回删除的项;
列表末尾插入数据:push(),push()接受任意数量的参数,并将它们添加数组末尾,并返回数组的最新长度。
列表开头插入数据:unshift(), 该方法在数组开头添加任意多个值,并返回新的数组长度。
let colors = new Array(); // 创建一个数组
let count = colors.push("red", "green"); // 推入两项
alert(count); // 2
count = colors.push("black"); // 再推入一项
alert(count); // 3
let item = colors.shift(); // 取得第一项
alert(item); // red
alert(colors.length); // 2
let colors = new Array(); // 创建一个数组
let count = colors.unshift("red", "green"); // 从数组开头推入两项
alert(count); // 2
count = colors.unshift("black"); // 再推入一项
alert(count); // 3
let item = colors.pop(); // 取得最后一项
alert(item); // green
alert(colors.length); // 2
9.排序方法
数组有两个方法对元素重新排序:
reverse(): 将数组元素反排列;
默认的sort() 会按照升序重新排列数组元素。默认的sort() 方法会在每一项上调用String()转型函数,然后比较字符串来决定顺序,即使数组中元素都是数值,也会先把数值转换成字符串再比较,排序。有的时候会出现意料之外的事情。
sort()方法可以接受一个比较函数,用来判断哪个值应该-排在前面;
也可以简写成箭头函数
values2.sort((a,b)=>a<b?1:a>b?-1:0)