塌陷
1:什么是数组塌陷?
一种索引向前递进的行为
当你从数组的前面或者中间位置删除一个数据的时候,都会向前递进
如果我们想删除数组[10,20,30,40,50]中的所有元素,仅仅使用数组的splice()方法并不能清空数组元素.
var arr = [10, 20, 30, 40];
for (var i = 0; i < arr.length; i++) {
arr.splice(i, 1);
}
运行结果为
这是因为当splice删除前面的元素之后,后面的元素会自动向前补位,而此时循环的索引已经+1,变成下一位的索引 。
2:塌陷的解决办法
方法1:固定循环次数 for每循环结束一次,就实时获取到数组的长度,删除数组元素的时候都从索引为0的位置删除,进而解决数组塌陷问题。
代码如下:
var arr = [10, 20, 30, 40];
var len = arr.length
for (var i = 0; i < len; i++) {
arr.splice(0, 1)
}
console.log(arr);
运行结果:
方法二:倒着删除,只删除最后一个,这样就不会出现删除一个元素的时候,索引向前递进的情况。
代码如下:
var arr = [10, 20, 30, 40];
//for循环开始时从数组的最后一个元素开始
for (var i = arr.length - 1; i >= 0; i--) {
// arr.splice(-1, 1)
// i 永远是最后一位
arr.splice(i, 1);
}
console.log(arr);
运行结果:
方法三:向后退一步,永远只删除第一个
arr.length 实时获取,删除到最后长度为0
代码如下:
var arr = [10, 20, 30, 40];
for (var i = 0; i < arr.length; i++) {
arr.splice(i, 1);
// 保持 i 一直为0
i--;
}
console.log(arr);
结果如下:
解决数组塌陷方法的总结
要么让数组不塌陷
- 从后面开始删除
- 倒着循环数组
要么就跟随塌陷回退
- 因为 i++ 必然会前进一步
- 在 i++ 之前执行一步 i--
- i-- 只有在执行了 删除操作以后, 才需要执行
数组去重
看一下下面这个数组:var arr = [1,2,1,1,3,2];
很明显的看出这个数组有相同的元素。
由此顾名思义可知数组去重是将数组中有相同重复的元素给去掉。
以下是我提供的三种数组去重方法
方法一:
准备一个新数组 ,遍历原始数组, 把原始数组内每一个依次插入到新数组内,在插入的时候, 要进行判断, 如果新数组内没有, 才插入
代码如下:
var arr = [11, 22, 33, 44, 55, 11, 33, 22, 99, 22];
var newArr = [];
for (var i = 0; i < arr.length; i++) {
// 遍历的元素是否存在于,新数组中
newArr.indexOf(arr[i]) == -1 ? newArr.push(arr[i]) : '';
}
console.log(newArr);
结果如下:
方法二: 数组索引不允重复,可以讲原数组的元素作为新数组的索引,然后在遍历新数组,将元素放到老数组中.
代码如下:
var arr = [11, 22, 33, 44, 55, 11, 33, 22, 99, 22];
var newArr = [];
arr.forEach(function (v, k) {
// 将老数组的元素,当做新数组的索引
newArr[v] = 1;
});
// 清空老数组
arr.length = 0;
// 新数组的索引是老数组的元素
newArr.forEach(function (v, k) {
arr.push(k)
});
console.log(arr);
结果如下:
方法三:利用对象方式 由于对象的属性名是不允许重复的,故可以将数组索引内容转化为对象的属性进行操作
代码如下:
var arr = [11, 22, 33, 44, 55, 11, 33, 22, 99, 22];
// 准备一个新对象
var obj = {}
for (var i = 0; i < arr.length; i++) {
obj[arr[i]] = '1'
}
// console.log(obj)
// 把原始数组置空
arr.length = 0
for (var k in obj) {
arr.push(k - 0)
}
console.log('去重之后 : ', arr)
结果如下: