pop/push, shift/unshift 方法
数组用例
一、JavaScript 中的数组既可以用作队列,也可以用作栈。它们允许你从首端/末端来添加/删除元素。
二、这在计算机科学中,允许这样的操作的数据结构被称为双端队列(deque)。
队列
一、队列(queue))是最常见的使用数组的方法之一。在计算机科学中,这表示支持两个操作的一个有序元素的集合:
- push在末端添加一个元素.
- shift取出队列首端的一个元素,整个队列往前移,这样原先排第二的元素现在排在了第一。
1、这两种操作数组都支持。
【示例】队列的应用在实践中经常会碰到。例如需要在屏幕上显示消息队列。 |
---|
数据结构栈
一、数组还有另一个用例,就是数据结构栈。
1、它支持两种操作:
- push在末端添加一个元素.
- pop从末端取出一个元素.
2、所以新元素的添加和取出都是从“末端”开始的。
二、栈通常被被形容成一叠卡片:要么在最上面添加卡片,要么从最上面拿走卡片:
三、对于栈来说,最后放进去的内容是最先接收的,也叫做 LIFO(Last-In-First-Out),即后进先出法则。而与队列相对应的叫做 FIFO(First-In-First-Out),即先进先出。
方法
作用于数组末端的方法
pop
一、取出并返回数组的最后一个元素:
| 【示例】```javascript let fruits = [“Apple”, “Orange”, “Pear”];
alert( fruits.pop() ); // 移除 “Pear” 然后 alert 显示出来
alert( fruits ); // Apple, Orange
|
| --- |
<a name="kcxzy"></a>
#### push
一、在数组末端添加元素
| 【示例】```javascript
let fruits = ["Apple", "Orange"];
fruits.push("Pear");
alert( fruits ); // Apple, Orange, Pear
1、调用fruits.push(…)与fruits[fruits.length] = …是一样的。 | | —- |
作用于数组首端的方法
shift
一、取出数组的第一个元素并返回它:
| 【示例】```javascript let fruits = [“Apple”, “Orange”, “Pear”];
alert( fruits.shift() ); // 移除 Apple 然后 alert 显示出来
alert( fruits ); // Orange, Pear
|
| --- |
<a name="BVt21"></a>
#### unshift
一、在数组的首端添加元素:
| 【示例】```javascript
let fruits = ["Orange", "Pear"];
fruits.unshift('Apple');
alert( fruits ); // Apple, Orange, Pear
| | —- |
二、push和unshift方法都可以一次添加多个元素:
| 【示例】```javascript let fruits = [“Apple”];
fruits.push(“Orange”, “Peach”); fruits.unshift(“Pineapple”, “Lemon”);
// [“Pineapple”, “Lemon”, “Apple”, “Orange”, “Peach”] alert( fruits );
|
| --- |
<a name="fLHtP"></a>
## 性能
一、push/pop方法运行的比较快,而shift/unshift比较慢。<br />
<a name="FFAIK"></a>
### 为什么作用于数组的末端会比首端快
一、让我们看看shift / unshift 在执行期间都发生了什么:
```javascript
fruits.shift(); // 从首端取出一个元素
1、只获取并移除数字0对应的元素是不够的。其它元素也需要被重新编号。
2、shift操作必须做三件事:
(1)移除索引为0的元素。
(2)把所有的元素向左移动,把索引1改成0,2改成1以此类推,对其重新编号。
(3)更新length属性。
3、数组里的元素越多,移动它们就要花越多的时间,也就意味着越多的内存操作。
4、unshift也是一样:为了在数组的首端添加元素,我们首先需要将现有的元素向右移动,增加它们的索引值。
二、那push/pop是什么样的呢?
fruits.pop(); // pop操作的行为:从末端取走一个元素
1、它们不需要移动任何东西。
2、如果从末端移除一个元素,pop方法要做的事情
(1)清理末端索引值
(2)缩短length就可以了。
3、 pop方法不需要移动任何东西,因为其它元素都保留了各自的索引。这就是为什么pop会特别快。
4、 push方法也是一样的。
splice(aSuncat-20210527:常用)
一、如何从数组中删除元素?
| 【示例】数组是对象,所以我们可以尝试使用delete:```javascript let arr = [“I”, “go”, “home”];
delete arr[1]; // remove “go”
alert( arr[1] ); // undefined
// now arr = [“I”, , “home”]; alert( arr.length ); // 3
1、元素被删除了,但数组仍然有 3 个元素,我们可以看到arr.length == 3。<br />2、这很正常,因为delete obj.key是通过key来移除对应的值。对于对象来说是可以的。但是对于数组来说,我们通常希望剩下的元素能够移动并占据被释放的位置。我们希望得到一个更短的数组。<br />3、所以应该使用特殊的方法。 |
| --- |
三、arr.splice方法可以说是处理数组的瑞士军刀。它可以做所有事情:添加,删除和插入元素。<br />1、语法是:
```javascript
arr.splice(start[, deleteCount, elem1, ..., elemN])
2、它从索引start开始修改arr:删除deleteCount个元素并在当前位置插入elem1, …, elemN。改变原始数组,最后返回已被删除元素的数组。
| 【示例】从索引1开始删除1个元素。```javascript let arr = [“I”, “study”, “JavaScript”];
arr.splice(1, 1); // 从索引 1 开始删除 1 个元素
alert( arr ); // [“I”, “JavaScript”]
|
| --- |
| 【示例】我们删除了 3 个元素,并用另外两个元素替换它们:```javascript
let arr = ["I", "study", "JavaScript", "right", "now"];
// remove 3 first elements and replace them with another
arr.splice(0, 3, "Let's", "dance");
alert( arr ) // now ["Let's", "dance", "right", "now"]
| | —- |
| 【示例】splice返回了已删除元素的数组:```javascript let arr = [“I”, “study”, “JavaScript”, “right”, “now”];
// 删除前两个元素 let removed = arr.splice(0, 2);
alert( removed ); // “I”, “study” <— 被从数组中删除了的元素
|
| --- |
| 【示例】我们可以将deleteCount设置为0,splice方法就能够插入元素而不用删除任何元素:```javascript
let arr = ["I", "study", "JavaScript"];
// 从索引 2 开始
// 删除 0 个元素
// 然后插入 "complex" 和 "language"
arr.splice(2, 0, "complex", "language");
alert( arr ); // "I", "study", "complex", "language", "JavaScript"
| | —- |
| 【项目示例5】项目中,删除符合某个条件的某一项
方法1、findIndex:项目中,可以先把某一项id符合某个条件的数据找出来,再删除这项```javascript
const categoryData = [
{
id: 1,
},
{
id: 2,
}
]
const id = 2;
// 先用findIndex找到符合要求的行的index,然后用slice复制数组,最后用splice删除1项 const index = categoryData.findIndex((item) => item.id === id); // index => 1 const newCate = categoryData.slice() newCate.splice(index, 1);
console.log(newCate); // 得到的数据如下 [ { id: 1, }, ]
方法2:filter(推荐)```javascript
const categoryData = [
{
id: 1,
},
{
id: 2,
}
]
const id = 2;
const newCate = categoryData.filter((item) => item.id !== id);
console.log(newCate);
// 得到的数据如下
[
{
id: 1,
},
]
| | —- |
四、允许负向索引
1、在这里和其他数组方法中,负向索引都是被允许的。它们从数组末尾计算位置
| 【示例】```javascript let arr = [1, 2, 5];
// 从索引 -1(尾端前一位) // 删除 0 个元素, // 然后插入 3 和 4 arr.splice(-1, 0, 3, 4);
alert( arr ); // 1,2,3,4,5
|
| --- |
<a name="NF8NM"></a>
# slice(aSuncat-20210527:常用)
一、arr.slice方法比arr.splice简单得多。<br />1、语法是:
```javascript
arr.slice([start], [end])
2、它会返回一个新数组,将所有从索引start到end(不包括end)的数组项复制到一个新的数组。start和end都可以是负数,在这种情况下,从末尾计算索引。
二、它和字符串的str.slice方法有点像,就是把子字符串替换成子数组。
| 【示例】```javascript let arr = [“t”, “e”, “s”, “t”];
alert( arr.slice(1, 3) ); // e,s(复制从位置 1 到位置 3 的元素)
alert( arr.slice(-2) ); // s,t(复制从位置 -2 到尾端的元素)
|
| --- |
三、我们也可以不带参数地调用它:arr.slice()会创建一个arr的副本。其通常用于获取副本,以进行不影响原始数组的进一步转换。<br />1、slice方法参数为空时,同concat方法一样,都是浅复制生成一个新数组。
| 【示例】项目中,级联选择,如果选择当前行,需要先把后面的数据清空,就用到了这个方法```json
// 数据根据categoryPids的长度来定循环几列
const pids = categoryPids.slice(0, level); // level:当前选择的是第几列
setCategoryPids([
...pids,
]);
| | —- |
concat
一、arr.concat创建一个新数组,其中包含来自于其他数组和其他项的值。
二、语法:
arr.concat(arg1, arg2...)
1、参数
- 它接受任意数量的参数 —— 数组或值都可以。
- 如果参数argN是一个数组,那么其中的所有元素都会被复制。否则,将复制参数本身。
2、结果是一个包含来自于arr,然后是arg1,arg2的元素的新数组。
| 【示例】```javascript let arr = [1, 2];
// create an array from: arr and [3,4] alert( arr.concat([3, 4]) ); // 1,2,3,4
// create an array from: arr and [3,4] and [5,6] alert( arr.concat([3, 4], [5, 6]) ); // 1,2,3,4,5,6
// create an array from: arr and [3,4], then add values 5 and 6 alert( arr.concat([3, 4], 5, 6) ); // 1,2,3,4,5,6
|
| --- |
二、通常,它只复制数组中的元素。其他对象,即使它们看起来像数组一样,但仍然会被作为一个整体添加:
| 【示例】```javascript
let arr = [1, 2];
let arrayLike = {
0: "something",
length: 1
};
alert( arr.concat(arrayLike) ); // 1,2,[object Object]
| | —- |
1、但是,如果类似数组的对象具有Symbol.isConcatSpreadable属性,那么它就会被concat当作一个数组来处理
| 【示例】此对象中的元素将被添加:```javascript let arr = [1, 2];
let arrayLike = { 0: “something”, 1: “else”,
length: 2 };
alert( arr.concat(arrayLike) ); // 1,2,something,else ``` | | —- |
【示例】以下js操作Array的方法中不能添加元素的是:() A. push B. pop C. unshift D. splice 答案:B |
---|