数组去重的多种实现方法
对象键值对处理(推荐)
Array.prototype.myUnique = function () {
//=>this:ary 我们需要操作的数组,如果不想改变原有的数组,我们需要把要操作的数组克隆一份一模一样的处理,处理的都是克隆的这个数组
let _this = [...this],
obj = {};
for (let i = 0; i < _this.length; i++) {
let item = _this[i];
if (typeof obj[item] !== 'undefined') {
//=>当前迭代的这一项在数组中已经存在,我们把这一项在数组中干掉
// _this.splice(i, 1); [后面项移位,消耗性能]
_this[i] = _this[_this.length - 1];
_this.length--;
i--;
continue;
}
obj[item] = true;
}
obj = null;
return _this;
};
双循环(不推荐)
Array.prototype.myUnique = function () {
//=>this:ary 我们需要操作的数组,如果不想改变原有的数组,我们需要把要操作的数组克隆一份一模一样的处理,处理的都是克隆的这个数组
let _this = [...this],
obj = {};
for (let i = 0; i < _this.length; i++) {
let item = _this[i];
if (typeof obj[item] !== 'undefined') {
//=>当前迭代的这一项在数组中已经存在,我们把这一项在数组中干掉
// _this.splice(i, 1); [后面项移位,消耗性能]
_this[i] = _this[_this.length - 1] ;
_this.length-- ;
i-- ;
continue ;
}
obj[item] = true ;
}
obj = null ;
return _this ;
};
indexOf:获取当前项在数组中第一次出现位置的索引,也能判断是否存在这一项(不存在获取的索引是-1),这个方法是不兼容IE6~8的
Array.prototype.myUnique = function () {
let _this = [...this];
//=>依次迭代数组中的每一项,验证当前项在数组中是否存在(不是和整个数组比较是否存在,而是和当前项的后面项比较是否存在=>类似于双FOR),存在把当前项干掉
for (let i = 0; i < _this.length; i++) {
let item = _this[i],
nextAry = _this.slice(i + 1);
if (nextAry.indexOf(item) > -1) {
_this[i] = _this[_this.length - 1];
_this.length--;
i--;
}
}
return _this;
};
排序后相邻去除法
先把数组进行排序,验证当前项和后一项是否相同,如果不相同,说明没有重复,我们把着于相提取出来保存即可
Array.prototype.myUnique = function () {
let _this = [],
ary = this.slice(0).sort((a, b) => a - b);
for (let i = 0; i < ary.length; i++) {
let item = ary[i],
next = ary[i + 1];
if (item !== next) {
_this.push(item);
}
}
return _this;
};
递归
函数自己调用自己执行就是递归 (递归是基于条件判断的:因为我们不能形成死递归,在某个条件下我们需要结束递归操作)
需求:数组扁平化(多维数组=>一维数组)
let ary = [1, [2, [3, [4, 5]]], [6, 7, [8, 9, [11, 12]], 10]]; //=>[1,2,3,4,5,6]
let result = [],
fn = function (ary) {
if (ary.length === 0) return;
for (let i = 0; i < ary.length; i++) {
let item = ary[i];
if (typeof item === 'object') {
fn(item);
} else {
result.push(item);
}
}
};
fn(ary);
console.log(result);
插入排序
插入排序:先把数组的第一项拿出来放在左手边,再从右手边拿出一张牌,到这分别和左手的牌进行比较,若比左手的牌大,则放在这张牌的后面,若比左手的牌小,继续往前比较,知道遇到左手牌比右手牌小的,放在这张牌后面,若比较到最前面也没有发现左手牌比右手这张牌小的,说明右手这张牌最小,则放在左手牌的最前面从右往左比较
var ary = [5,2,3,3,5,44,12,14,88,99,56,88,99,15,15,55,66,88];
var left = ary.splice(0,1);
for(var i =0; i<ary.length;i++){
var curR = ary[i];//右手边的每张牌
for(var j =left.length-1; j>=0; ){
var curL = left[j];//左手边的每张牌
if (curR>curL){
left.splice(j+1,0,curR);
break;
}else{//右手牌比左手牌小,则继续往前跟左手牌进行比较
j--;
if (j == -1){
left.unshift(curR);
}
}
}
}
从左往右比较
var ary = [5,88,99,99,99,10,100];
var left = ary.splice(0,1);
for(var i =0; i<ary.length; i++){
var curR = ary[i];//右手边的每张牌
for(var j = 0;j<left.length;){
var curL = left[j];
if (curR<curL){//若右手牌比左手小//有可能重复,所以加一个等号。
left.splice(j,0,curR);//则放在这张牌的前面
break;
}else{
j++;
if(j == left.length){//右手牌比左手牌大,则继续往前跟左手牌进行比较
left.push(curR);
break;//加上break进行下一轮比较
}
}
}
}
console.log(left);
冒泡排序
//冒泡排序:小的往前排,大的往后排,实现从小到大排列
//两两比较的方式,若前一项比后一项小,则保持原排列位置,若前一项比后一项大,则他俩交换位置,这样一轮
var ary = [2, 15, 364, 4, 2655, 514, 12, 5461, 4];
for (var j = 0; j < ary.length; j++) {//控制轮数
for (var i = 0; i < ary.length - 1- j; i++) {//每轮比较的次数
// ary[i]前一项 ary[i+1]后一项
if (ary[i] > ary[i + 1]) {
var temp = null;//借助一下中间变量
temp = ary[i];
ary[i] = ary[i + 1];
ary[i + 1] = temp;
}
}
}
console.log(ary);
快速排序
//快速排序:去除数组的中间项,将其他项跟中间项进行比较,若比中间项小,放入left数组中,若比中间项大,则放入righth数组当中,left和right重复以上逻辑
var ary = [12, 3, 4, 1, 41, 2, 11, 444, 1000, 47];
去除数组中的中间项ary.length/2
function quickSort(ary) {
if(ary.length<=1){
return ary;
}
var pointIndex = Math.floor(ary.length / 2)//取出中间项
var pointValue = ary.splice(pointIndex, 1)[0];
var left = [];
var right = [];
for (var i = 0; i < ary.length; i++) {
var cur = ary[i];
if (cur <= pointValue) {
left.push(cur);
} else {
right.push(cur);
}
}
return quickSort(left).concat(pointValue,quickSort(right))
}
console.log(quickSort(ary));