JS基础(1)——数组扁平化、去重、类数组转化为数组

JS基础(1)——数组扁平化、去重、类数组转化为数组

一、数组扁平化

const arr1 = [1, [2, [3, [4, 5]]], 6];
// => [1, 2, 3, 4, 5, 6]
1.ES6的flat()
const res1_1 = arr1.flat(Infinity);

Array.prototype.flat() 特性总结:

  • 用于将嵌套的数组扁平化,变成一维的数组。该方法返回一个新数组,对原数据没有影响。
  • 不传参数时,默认扁平化一层,可以传入一个整数,表示想要扁平化的层数。
  • 传入 <=0 的整数将返回原数组,不扁平化
  • Infinity 关键字作为参数时,无论多少层嵌套,都会转为一维数组
  • 如果原数组有空位,Array.prototype.flat() 会跳过空位。即删除空位。

局限:必须考虑兼容性

手写 flat函数

// 传入两个参数:数组arr  扁平化层数depth(默认是一层)
function flat(arr, depth = 1) {
  return depth > 0 ? // 层数大于0才进行扁平化
    arr.reduce((acc, cur) => { // acc:reducer 函数的返回值(累计器),cur:当前值(arr 中遍历到的当前元素值)
      if(Array.isArray(cur)){ // 当前值是 数组
        return [...acc, ...flat(cur, depth - 1)]; // 递归执行 flat 函数,插入返回数组中 累计器的值后面
      }
      return [...acc, cur]; // 当前值不是数组,直接插入返回数组中 累计器后面
    }, [])
    : arr; // 扁平化层数小于等于0,直接返回原数组 ar
}
2.正则
const res1_2 = JSON.stringify(arr1).replace(/(\[|\])/g, '').split(',');
const res1_3 = JSON.parse('[' + JSON.stringify(arr1).replace(/(\[|\])/g, '') + ']');
//const res1_3 = JSON.parse(`[${JSON.stringify(arr1).replace(/(\[|\])/g, '')}]`);
3.reduce()递归
const flatten = arr => {
  return arr.reduce((pre,cur) => {
    return pre.concat(Array.isArray(cur) ? flatten(cur) : cur); 
    // return pre.concat(cur instanceof Array ? flatten(cur) : cur);
  },[]);
  // return Array.isArray(arr)
  //   ? arr.reduce( (acc, cur) => [...acc, ...flatten(cur)] , []) 
  //   : [arr];
}
const res1_4 = flatten(arr1);
4.函数递归
const res1_5 = [];
const fn = arr => {
  for(let i = 0; i < arr.length; i++){
    Array.isArray(arr[i]) ? fn(arr[i]) : res1_5.push(arr[i]);
  }
}
fn(arr1);
function flat(arr) {
  let result = []
  for (const item of arr) {
    item instanceof Array ? result = result.concat(flat(item)) : result.push(item)
  }
  return result
}
const res1_5_2 = flat(arr1);
5.迭代+展开运算符
// 每次while都会合并一层的元素,这里第一次合并结果为[1, 1, 2, 1, 2, 3, [4,4,4]]
// 然后arr.some判定数组中是否存在数组,因为存在[4,4,4],继续进入第二次循环进行合并
let arr = [1, [1,2], [1,2,3,[4,4,4]]]
while (arr.some(Array.isArray)) {
  arr = [].concat(...arr);
}

二、数组去重

const arr2 = [1, 1, '1', 17, true, true, false, false, 'true', 'a', [], [], {}, {}];
// => [1, '1', 17, true, false, 'true', 'a', [], [], {}, {}]
1.ES6的Set
const res2_1 = Array.from(new Set(arr2));
2.两层for+splice
const unique1 = arr =>{
  let len = arr.length;
  for(let i = 0; i < len; i++){
    for(let j = i + 1; j < len; j ++){
      if(arr[i] === arr[j]){
        arr.splice(j,1);
        len --;
        j --;
      }
    }
  }
  return arr;
}
const res2_2 = unique1(arr2);
3.indexOf
const unique2 = arr => {
  if (!Array.isArray(arr)) {
    console.log('type error!')
    return}
  const res = [];
  for(let i = 0; i < arr.length; i++){
    if(res.indexOf(arr[i]) === -1){
      res. push(arr[i]);
    }
  }
  return res;
}
const res2_3 = unique2(arr2);
4.includes
const unique3 = arr => {
  if (!Array.isArray(arr)) {
    console.log('type error!')
    return}
  const res = [];
  for(let i = 0; i < arr.length; i++){
    if(!res.includes(arr[i])){
      res. push(arr[i]);
    }
  }
  return res;
}
const res2_4 = unique3(arr2);
5.hasOwnProperty
const unique7 = arr => {
  var obj = {};
  return arr.filter(function(item, index, arr){
    return obj.hasOwnProperty(typeof item + item) ? false : (obj[typeof item + item] = true)
  })
}
const res2_8 = unique7(arr2);
6.filter
const unique4 = arr => {
  return arr.filter((item,index) => {
    return arr.indexOf(item) === index;
  })
}
const res2_5 = unique4(arr2);
7.ES6的map
const unique5 = arr => {
  const map = new Map();
  for(let i = 0; i < arr.length; i++){
    if(!map.has(arr[i])){
      map.set(arr[i], true);
    }
  }
  return res;
}
const res2_6 = unique5(arr2);
8.sort()
const unique6 = arr => {
  if (!Array.isArray(arr)) {
    console.log('type error!');
    return;
  }
  arr = arr.sort();
  var res = [arr[0]];
  for(let i = 1; i < arr.length; i++){
    if(arr[i] !== arr[i-1]){
      res.push(arr[i]);
    }
  }
  return res;
}
const res2_7 = unique6(arr2);
9.对象属性不能相同

(这种数组去重的方法有问题,有待改进)

function unique(arr) {
    if (!Array.isArray(arr)) {
        console.log('type error!')
        return
    }
    var arrry= [];
     var  obj = {};
    for (var i = 0; i < arr.length; i++) {
        if (!obj[arr[i]]) {
            arrry.push(arr[i])
            obj[arr[i]] = 1
        } else {
            obj[arr[i]]++
        }
    }
    return arrry;
}
    var arr = [1,1,'true','true',true,true,15,15,false,false, undefined,undefined, null,null, NaN, NaN,'NaN', 0, 0, 'a', 'a',{},{}];
        console.log(unique(arr))
//[1, "true", 15, false, undefined, null, NaN, 0, "a", {…}]    //两个true直接去掉了,NaN和{}去重

三、类数组转化为数组

类数组是具有length属性,但不具有数组原型上的方法。
常见的类数组有arguments、DOM操作方法返回的结果。

<div id="d1"></div>
<div id="d2"></div>
<div id="d3"></div>
1.Array.from
 const res3_1 = Array.from(document.querySelectorAll('div'));
2.Array.prototype.slice.call

原理:数组的slice()方法可以从已有数组中返回一个新数组,它可以接受两个参数arr.slice(start,end),第一个参数规定从何处开始选取,第二个参数表示从何处选取结束,如果不传参将返回原数组的一个副本,但该方法不会修改原数组,而是返回截取的新数组。

const res3_2 = Array.prototype.slice.call(document.querySelectorAll('div'));
// Array.prototype.slice.apply(document.querySelectorAll('div'))
3.扩展运算符
const res3_3 = [...document.querySelectorAll('div')];
4.Array.prototype.concat.apply
const res3_4 = Array.prototype.concat.apply([], document.querySelectorAll('div'))
// Array.prototype.concat.call([], ...document.querySelectorAll('div'))

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值