【前端js】算法全归纳(一)数组:最全数组操作合集


本文主要从应用来讲数组api的一些操作,如一行代码扁平化n维数组、数组去重、求数组最大值、数组求和、排序、对象和数组的转化等。


1.扁平化n维数组

1.简单方法(牛客网不支持)

ES10扁平数组的api, n表示维度, n值为 Infinity时维度为无限大。

Array.flat(n)

[1,[2,3]].flat(2) //[1,2,3]
[1,[2,3,[4,5]].flat(3) //[1,2,3,4,5]
[1[2,3,[4,5[...]].flat(Infinity) //[1,2,3,4...n]
2.兼容方法

先判断是否有嵌套数组,有的情况下,...arr展开操作每次能去除一层嵌套数组,直到去除掉所有嵌套数组为止

function flatten(arr) {
  while (arr.some(item => Array.isArray(item))) {
    arr = [].concat(...arr);
  }
  return arr;
}
flatten([1, [2, 3]]); //[1,2,3]
flatten([1, [2, 3, [4, 5]]]); //[1,2,3,4,5]


2.去重

1.简单方法(不能对嵌套数组,对象数组去重)

利用集合set不重复的特性:set是ES6新出来的一种一种定义不重复数组的数据类型
Array.from是将类数组转化为数组
...是扩展运算符,将set里面的值转化为arg1,arg2,arg3(类似数组的toString

Array.from(new Set([1,2,3,3,4,4])) //[1,2,3,4]
[...new Set([1,2,3,3,4,4])] //[1,2,3,4]
2.兼容方法(可以对嵌套数组,对象数组去重)
  let obj = {};//对照对象
  for (var i = 0; i < result2.length; i++) {
    // 判断当前项是否遍历过,是则删除,否存入obj以作对照

    if (obj[result2[i]]) {
      result2.splice(i, 1);
      i--; //数组删除了一项,要把i回退一下,不然会跳过下一项不去遍历
    } else {
      obj[result2[i]] = 1;
    }
  }
 


3.排序

1.简单方法

arrayObject.sort(sortby) sortby可选。规定排序顺序。必须是函数。

  1. 如果调用该方法时没有使用参数,将按照字符编码的顺序进行排序。要实现这一点,首先应把数组的元素都转换成字符串(如有必要),以便进行比较。
  2. 如果想按照其他标准进行排序,就需要提供比较函数,该函数要比较两个值,然后返回一个用于说明这两个值的相对顺序的数字。比较函数应该具有两个参数 a 和 b,函数返回值大于0的时候,交换ab的位置,a排在b的后面。
[1,2,3,4].sort(); // [1, 2,3,4],默认是升序
[1,2,3,4].sort((a, b) => b - a); // [4,3,2,1] 降序
2.兼容方法

冒泡排序
快速排序
选择排序


4.最大值

1.简单方法
方法一:max()

Math.max(n1,n2,n3,...,nX)
max() 方法可返回两个指定的数中带有较大的值的那个数
n1,n2,n3,…,nX 可选。1 或多个值。在 ECMASCript v3 之前,该方法只有两个参数。
返回值:参数中最大的值。如果没有参数,则返回 -Infinity。如果有某个参数为 NaN,或是不能转换成数字的非数字值,则返回 NaN。
http://www.runoob.com/jsref/jsref-max.html

Math.max(...[1,2,3,4]) //4
Math.max.apply(this,[1,2,3,4]) //4
方法二:reduce()迭代比较(兼容max方法只支持两个参数的情况)

reduce是ES5的数组api,参数有函数和默认初始值;
函数有四个参数,pre(上一次的返回值),cur(当前值),curIndex(当前值索引),arr(当前数组)

[1,2,3,4].reduce((prev, cur)=> (
 Math.max(prev,cur))
,0)//4

例题

/**第一题
 * 说明:获取一个数字数组中的最大值
 * 示例:
 * 输入:[1, 5, 3, 9, 2, 7]
 * 输出:9
 */
var arr = [1, 5, 3, 9, 2, 7];
//方法一
Math.max(...arr);//9
//方法二
Math.max.apply(this,arr);//9
Math.max.call(this,...arr);//9
//方法三
arr.reduce((prev, cur)=> (
 Math.max(prev,cur))
,0)//9

5.打乱顺序

//添加原型方法
Solution.prototype.shuffle = function() {
  //交换数组元素顺序
  const swap = (a, i, j) => {
    [a[i], a[j]] = [a[j], a[i]];
  };
  let arr = this.nums.slice(); //深拷贝数组,不然会改变this.nums,影响reset的输出

  for (let i = arr.length - 1; i >= 0; i--) {//从后往前遍历数组
    //swap(arr, i, Math.floor(Math.random() * (arr.length - i + 1))); //每次
    swap(arr, i, Math.floor(Math.random() * i+1));//交换i和0-i中随机位置的元素
  }
  return arr;
};

参考 https://segmentfault.com/a/1190000018549643

6. 移除数组中的元素(牛客网-js能力测评)

题目
移除数组 arr 中的所有值与 item 相等的元素,直接在给定的 arr 数组上进行操作,并将结果返回

思路

  1. 特殊情况,空数组,但数组
  2. 为了避免splice方法影响接下来的遍历,从后往前遍历数组
function removeWithoutCopy(arr, item) {
  if (arr.length === 0) return []; //空数组
  if (arr.length === 1) return item === arr[0] ? arr : []; //单个元素数组
  for (var i = arr.length - 1; i >= 0; i--) {
    //从后往前遍历,每次删除以后不用重新修改i
    arr[i] === item ? arr.splice(i, 1) : "";
  }
  return arr;
}

7. 数组首尾添加元素(牛客网-js能力测评)

题目1
在数组 arr 末尾添加元素 item。不要直接修改数组 arr,结果返回新的数组
.concat()方法会返回一个新数组

function append(arr, item) {
 return arr.concat(item);
}

题目2
在数组 arr 开头添加元素 item。不要直接修改数组 arr,结果返回新的数组
注意添加的顺序:

function prepend(arr, item) {
  return [].concat(item,arr);
}
8. 数组首尾删除元素(牛客网-js能力测评)

题目1
删除数组 arr 最后一个元素。不要直接修改数组 arr,结果返回新的数组

思路
1.使用不修改原数组的删除api——slice
2.使用修改原数组的删除api——splice/pop/shift,为了不修改原来的数组,需要先拷贝数组arr.slice(0),from,[...arr]都可以实现深拷贝
3. .pop()方法返回的是出栈元素,这里要求返回修改后的数组

function truncate(arr) {
  var res = arr.slice(0);
  res.pop();
  return res;
}

题目2
删除数组 arr 第一个元素。不要直接修改数组 arr,结果返回新的数组

function curtail(arr) {
    return arr.slice(1);
}
9.插入元素(牛客网-js能力测评)

题目
在数组 arr 的 index 处添加元素 item。不要直接修改数组 arr,结果返回新的数组
思路

  1. 使用splice插入元素,因为splice修改愿数组,所以需要先拷贝数组;
  2. 因为splice返回的是被删除的元素,所以需要先调用方法,再返回拷贝数组,不能直接返回splice的结果
function insert(arr, item, index) {
    var res = arr.slice(0);
    res.splice(index,0,item);
    return res;
}
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值