javascript数组方法 == js数组去重 == js中数组排序(冒泡、快速、插入)== js中数组扁平化处理

javascript数组方法 == js数组去重

参看如下链接:

1.https://www.cnblogs.com/cauliflower/p/11267809.html

2.https://www.cnblogs.com/zyfeng/p/10541133.html

===========================================================

js数组去重

情境:

将数组var arr = [1,1,‘true’,‘true’,true,true,15,15,false,false, undefined,undefined, null,null, NaN, NaN,‘NaN’, 0, 0, ‘a’, ‘a’,{},{}]中重复的值过滤掉

1、 ES6-set

使用ES6中的set是最简单的去重方法
var arr  = [1,1,'true','true',true,true,15,15,false,false, undefined,
undefined, null,null, NaN,NaN,'NaN', 0, 0, 'a', 'a',{
    
    },{
    
    }];
 
function arr_unique1(arr){
    
    
return  [...new Set(arr)];
//或者
//return  Array.from(new Set(arr));
}
arr_unique1(arr);
 /* (13)[1, "true", true, 15, false,
 undefined, null, NaN, "NaN", 0, "a", {…}, {…}]*/

该方法可以说是最完美的方法,就是需要环境支持ES6

2、利用Map数据结构去重

创建一个空Map数据结构,遍历需要去重的数组,把数组的每一个元素作为key存到Map中。由于Map中不会出现相同的key值,所以最终得到的就是去重后的结果。

function arr_unique2(arr) {
    
    
  let map = new Map();
  let array = new Array();  // 数组用于返回结果
  for (let i = 0; i < arr.length; i++) {
    
    
    if(map .has(arr[i])) {
    
      // 如果有该key值
      map .set(arr[i], true);
    } else {
    
    
      map .set(arr[i], false);   // 如果没有该key值
      array .push(arr[i]);
    }
  }
  return array ;
}

 console.log(arr_unique2(arr)); 
 /*(13) [1, "a", "true", true, 15, false, 1, {…}, null, NaN, NaN, 
 "NaN", 0, "a", {…}, undefined]*/

3、 利用递归去重


function arr_unique3(arr) {
    
    
     var array= arr;
     var len = array.length;
     array.sort(function(a,b){
    
       //排序后更加方便去重
     return a - b;
    })
    
 function loop(index){
    
    
        if(index >= 1){
    
    
            if(array[index] === array[index-1]){
    
    
                array.splice(index,1);
            }
            loop(index - 1);    //递归loop,然后数组去重
        }
    }
    loop(len-1);
    return array;
}
 
console.log(arr_unique3(arr)); 
/*(14) [1, "a", "true", true, 15, false, 1, {…}, null, NaN, NaN,
 "NaN", 0, "a", {…}, undefined]*/

4、 forEach + indexOf


function arr_unique4(arr){
    
    
var res = [];
arr.forEach((val,index)=>{
    
    
if( res.indexOf(val) === -1 ){
    
    
res.push(val);
}
});
return res;
}

console.log(arr_unique4(arr)); 
/* (14) [1, "true", true, 15, false, undefined, null, NaN,
 NaN, "NaN", 0, "a", {…}, {…}]*/

该方法的不足之处在于无法对NaN进行过滤,原因是var a = [1, NaN , 2]; a.indexOf(NaN) === -1;,改善的方法是使用includes方法

5、 filter+indexOf


function arr_unique5(arr){
    
    
return  arr.filter((val,index,item)=>{
    
    
return item.indexOf(val) === index;
});
}

arr_unique5(arr); 
/*(12) [1, "true", true, 15, false, undefined, null, "NaN", 0, "a", {…}, {…}]*/

美中不足的地方在于漏掉了NaN,原因同方法四

6、 forEach + includes


function arr_unique6(arr){
    
    
var res = [];
arr.forEach((val)=>{
    
    
if( ! res.includes(val) ){
    
    
res.push(val);
}
});
return res;
}
arr_unique6(arr);
 /* (13) [1, "true", true, 15, false, undefined, null, NaN,
  "NaN", 0, "a", {…}, {…}]*/

该方法也算是比较完美,没有什么遗漏的地方

7、 reduce + includes


function  arr_unique7(arr){
    
    
return arr.reduce( (prev, cur )=>{
    
    
if(  ! prev.includes(cur) ){
    
    
prev.push(cur);
}
return prev;
} ,[]);
}
arr_unique7(arr);
 /*(13)[1, "true", true, 15, false, undefined, null, NaN, "NaN",
  0, "a", {…}, {…}]*/

8、 嵌套循环+splice


function arr_unique8(arr){
    
    
for(var i = 0 ; i < arr.length; i++){
    
    
for( var j = i + 1; j < arr.length; j++){
    
    
if( arr[i] === arr[j] ){
    
    
arr.splice(j,1);
}
}
}
return arr;
}
arr_unique8(arr);
 /*(14) [1, "true", true, 15, false, undefined, null, NaN, NaN, "NaN"
 , 0, "a", {…}, {…}]*/

这是最麻烦的方法,效率十分低下,每一个循环都会去动态获取数组的length。且该方法无法过滤掉NaN,因为NaN === NaN的结果为false。

9、 hash+hasOwnProperty+JSON.stringify(终级版)


function arr_unique9(arr){
    
    
var hash = {
    
    };
return arr.filter( (val)=>{
    
    
return hash.hasOwnProperty( typeof  val + JSON.stringify(val) )
 ? false : hash[typeof val + JSON.stringify(val)] = true ;
});
}
arr_unique9(arr);
/*(12) [1, "true", true, 15, false, undefined, null, NaN, "NaN", 0, "a", {…}]*/

这种方法是终极版的,因为它可以进行数组中的对象元素的去重!前面的几种方法是不可以进行对象去重的。不过话说回来,JS中的对象是本身就是一个地址的引用,比如 {} == {} ;//false,两者是两个不同的对象,这里我将其进行JSON.stringify进行简化。
经亲测,使用ES6的Set和Map效率最高,reduce()和sort()效率还可以,双层循环效率最低。
数组去重大全,你,get到了吗~

===========================================================

js中数组排序(冒泡、快速、插入)

1.冒泡排序法

将数组中的相邻两个元素进行比较,将比较大(较小)的数通过两两比较移动到数组末尾(开始),执行一遍内层循环,确定一个最大(最小)的数,外层循环从数组末尾(开始)遍历到开始(末尾)
在这里插入图片描述


function MaoPaoSort(arr){
    
    
        for(var i = 0;i<arr.length-1;i++) {
    
    
            for(var j = 0;j<arr.length-i-1;j++){
    
    
                if(arr[j]>arr[j+1]){
    
    
                    //把大的数字放到后面
                    var str = arr[j];
                    arr[j] = arr[j+1];
                    arr[j+1] = str;
                }
            }
        }
    }
    var arr = [3,5,1,2,7,8,4,5,3,4];
    //console.log(arr);[3,5,1,2,7,8,4,5,3,4];
    MaoPaoSort(arr);
    //console.log(arr);[1, 2, 3, 3, 4, 4, 5, 5, 7, 8]

2. 插入排序法(插队排序)

将要排序的数组分成两部分,每次从后面的部分取出索引最小的元素插入到前一部分的适当位置

在这里插入图片描述

  • 从第一个元素开始,该元素可以认为已经被排序;
  • 取出下一个元素,在已经排序的元素序列中从后向前扫描;
  • 如果该元素(已排序)大于新元素,将该元素移到下一位置;
  • 重复步骤3,直到找到已排序的元素小于或者等于新元素的位置;
  • 将新元素插入到该位置后;
  • 重复步骤2~5。

function InsertSort(arr) {
    
    
  let len = arr.length;
  let preIndex, current;
  for (let i = 1; i < len; i++) {
    
    
    preIndex = i - 1;
    current = arr[i];
    while (preIndex >= 0 && current < arr[preIndex]) {
    
    
      arr[preIndex + 1] = arr[preIndex];
      preIndex--;
    }
    arr[preIndex + 1] = current;
  }
  return arr;
}
 
var arr = [3,5,7,1,4,56,12,78,25,0,9,8,42,37];
InsertSort(arr);

3.快速排序

在看完上面的东西之后,不知道大家有没有发现在实际的工作中如果数据量过大,数组比较复杂,通过两次遍历,同时会带来性能上的问题,不用慌,我们还可以用快速排序的方法进行解决,快速排序对冒泡排序的一种改进

实现思路是,将一个数组的排序问题看成是两个小数组的排序问题,以一个数为基准(中间的数),比基准小的放到左边,比基准大的放到右边,而每个小的数组又可以继续看成更小的两个数组,一直递归下去,直到数组长度大小最大为2。


function quickSort(arr){
    
    
   //如果数组长度小于1,没必要排序,直接返回
   if(arr.length<=1) return arr;
   //pivot 基准索引,长度的一半
   let pivotIndex = Math.floor(arr.length/2);//奇数项向下取整
   //找到基准,把基准项从原数组删除
   let pivot = arr.splice(pivotIndex,1)[0];
   //定义左右数组
   let left = [];
   let right = [];
   //把比基准小的放left,大的放right
   arr.forEach(element => {
    
    
       if(element<pivot){
    
    
           left.push(element)
       }else{
    
    
           right.push(element)
       }
   });
   return quickSort(left).concat([pivot],quickSort(right))
}
    
var arr=[4,56,3,67,44,5,66];
console.log(quickSort(arr));//[3, 4, 5, 44, 56, 66, 67]

在这里插入图片描述

===========================================================

js中数组扁平化处理

经典面试题,项目中用js数组操作的地方很多,js数组扁平化是其中一种

什么是数组扁平化?

数组扁平化就是将一个多维数组转换为一个一维数组

实现基本方式

1、对数组的每一项进行遍历。
2、判断该项是否是数组。
3、如果该项不是数组则将其直接放进新数组。
4、是数组则回到1,继续迭代。
5、当数组遍历完成,返回这个新数组。

1.常规方式 递归处理


Array.prototype.flatten = function () {
    
    
  var resultArr = [];
  var len = this.length;
  for (var i = 0; i < len; i ++) {
    
    
    if (Array.isArray(this[i])) {
    
    
        resultArr = resultArr.concat(this[i].flatten());
    } else {
    
    
      resultArr.push(this[i]);
    }
  }
  return resultArr;
}
var arr=[1,2,3,[4,5,'hello',['world',9,666]]]
console.log(arr.flatten())//[1, 2, 3, 4, 5, "hello", "world", 9, 666]

2.使用reduce方法


Array.prototype.flatten = function () {
    
    
  return this.reduce(function (prev, cur, curIndex, arr) {
    
    
      return Array.isArray(cur) ? prev.concat(cur.flatten()) 
      : prev.concat(cur); 
  }, []);
}


Array.prototype.flatten = function () {
    
    
  return this.reduce(function (prev, cur, curIndex, arr) {
    
    
      return Array.isArray(cur) ? prev.concat(cur.flatten())
       : prev.concat(cur); 
  }, []);
}

3. yield*的用法,天才级别的扁平化方式


function* iterTree(tree){
    
    
      if(Array.isArray(tree)){
    
    
          for(let i = 0 ;i<tree.length;i++){
    
    
              yield* iterTree(tree[i]);
          }
      }else{
    
    
          yield tree;
      }
  }
 let arr1 = [1, 2, ['a', 'b', ['中', '文', [1, 2, 3, [11, 21, 31]]]], 3];
  let list=[]
for (const x of iterTree(arr1)) {
    
    
    list.push(x)
  }
  console.log(list);//[1, 2, "a", "b", "中", "文", 1, 2, 3, 11, 21, 31, 3]

4. es6中的flat函数也可以实现数组的扁平化


let arr1 = [1,2,['a','b',['中','文',[1,2,3,[11,21,31]]]],3];
 console.log( arr1.flat( Infinity ) ); 
 

5.扩展运算符


//ES6 增加了扩展运算符,用于取出参数对象的所有可遍历属性,拷贝到当前对象之中:

var arr = [1, [2, [3, 4]]];
console.log([].concat(...arr)); // [1, 2, [3, 4]]
//我们用这种方法只可以扁平一层,但是顺着这个方法一直思考,我们可以写出这样的方法:

// 改进
var arr = [1, [2, [3, 4]]];

function flatten(arr) {
    
    

    while (arr.some(item => Array.isArray(item))) {
    
    
        arr = [].concat(...arr);
    }

    return arr;
}

console.log(flatten(arr))

猜你喜欢

转载自blog.csdn.net/WLIULIANBO/article/details/110677761