JavaScript数组常用操作多种方案汇总(扁平化,去重等)

记录JS中数组常用操作的多种方案

写在前面

定义一个空对象,后续的方法都添加到该对象上。

const _ = {

}

数组去重

问题描述

const arr = [0, 0, 1, 1, 1, 2, 2, 3, 3, 4, 1, 2]

去除重复数字得到:

[ 0, 1, 2, 3, 4 ]

方案

1. ES6 Set

_.uniqV1 = arr => [...new Set(arr)];

或者

_.uniqV1 = arr => Array.from(new Set(arr));

2. 双层for循环

遍历原始数组,发现重复的项则用splice移除。

_.uniqV4 = arr => {
  for (let i = 0; i < arr.length; i++) {
    for (let j = i + 1; j < arr.length; j++) {
      if (arr[i] === arr[j]) {
        arr.splice(j, 1);
        j--;
      }
    }
  }
  return arr;
}

3. for 循环 额外空间

_.uniqV2 = arr => {
  const res = [];
  for (let i = 0; i < arr.length; i++) {
    if (res.indexOf(arr[i]) === -1) {
      res.push(arr[i]);
    }
  }
  return res;
}

4. Array.prototype.filter()

filter过滤数组,返回当前元素在原始数组中的第一个索引和当前索引值相等的项即可。

_.uniqV3 = arr => arr.filter((item, index, arr) => {
  return arr.indexOf(item, 0) === index;
});

5. 排序 + 双指针

起初快慢指针指向数组头 arr[i] = arr[j] = arr[0]
当arr[i] !== arr[j] 时,i向前移动一位,同时把arr[j] 赋值给 arr[i]
j 向前移动一位

_.uniqV5 = arr => {
  arr.sort();
  // i 慢指针 j 快指针
  let [i, j] = [0, 0];
  while (j < arr.length) {
    if (arr[j] !== arr[i]) {
      i++;
      arr[i] = arr[j];
    }
    j++;
  }
  return arr.slice(0, i + 1)
}

数组扁平化

问题描述

给出如下数组:

const arr = [
  [1, 2, 2],
  [3, 4, 5, 5],
  [6, 7, 8, 9, [11, 12, [12, 13, [14]]]], 10
];

使其扁平化后得到:

[
   1,  2,  2, 3,  4,  5,  5,
   6,  7,  8, 9, 11, 12, 12,
  13, 14, 10
]

方案

1. Array.prototype.flat()

Array.prototype.flat()

参数
depth 可选
指定嵌套数组结构扁平化的深度。默认值为1

这里我们指定深度为Infinity,表示无论嵌套多少层都要展平。

_.flattenV1 = arr => arr.flat(Infinity);

2. Array.prototype.toString()

_.flattenV2 = arr => arr.toString().split(',').map(item => parseInt(item));

无论数组嵌套多深,调用toString()方法都会的到又逗号,拼接而成的字符串,例如:

console.log(arr.toString()) // "1,2,2,3,4,5,5,6,7,8,9,11,12,12,13,14,10"

3. for 循环 递归

初始化一个空数组res
循环遍历原始数组arr

若当前项不是数组,将其放入数组res中
否则,递归当前项

_.flattenV3 = (arr, res = []) => {
  for (let i = 0; i < arr.length; i++) {
    if (Array.isArray(arr[i])) {
      _.flattenV3(arr[i], res);
    } else {
      res.push(arr[i]);
    }
  }
  return res;
}

4. Array.prototype.reduce()

这个版本其实是上面For循环的简化版。

利用数组的reduce方法遍历数组 前一项pre,当前项cur
将pre初始化为空数组[]
若当前项cur不是数组

将其合并到pre中
否则,递归当前项

_.flattenV4 = arr => arr.reduce((pre, cur) => pre.concat(Array.isArray(cur) ? flatten(cur) : cur), []);
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值