js 数组一些高级操作

js 数组一些高级操作

js 数组一些高级操作

参考地址:
JS 面试之数组的几个不 low 操作

前言

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

记录一:扁平化 n 维数组

[1, [2, 3]].flat(2); // [1, 2, 3]
[1, [2, 3, [4, 5]]].flat(3); // [1, 2, 3, 4, 5]

     
     

Array.flat(n) 是 ES10 扁平化数组的 api, n 表示维度, n 值为 Infiniti 时维度为无限大。

js 实现:利用递归和数组合并方法 concat 实现扁平。

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

flatten([1, [2, 3]]); // [1, 2, 3]

记录二:去重

Array.from(new Set([1, 2, 3, 2, 4])); // [1, 2, 3, 4]
[...new Set([1, 2, 3, 3, 4, 4])]; // [1, 2, 3, 4]

 
 
  1. Set 是 ES6 新出来的一种定义不重复数组的数据类型。
  2. Array.from 是将类数组转化为数组。
  3. … 是扩展运算符,将 set 里面的值转化为字符串。

js 实现:可以根据双层循环过滤掉重复项。

Array.prototype.distinct = function() {
  var arr = this,
    result = [],
    i,
    j,
    len = arr.length;
  for(i = 0; i < len; i++) {
    for(j = i + 1; j < len; j++) {
      if(arr[i] === arr[j]) {
        j = ++ i;
      }
    }
    result.push(arr[i]);
  }
  return result;
};
[1, 2, 2, 3].distinct(); // [1, 2, 3];

 
 

记录三:排序

[1, 2, 3, 4].sort(); // [1, 2, 3, 4] 默认是升序
[1, 2, 3, 4].sort((a, b) => b - a); // [4, 3, 2, 1]

 
 

sort 是 js 内置的排序方法,参数为一个函数

js 实现:冒泡排序

Array.prototype.bubleSort = function() {
  let arr = this,
    len = arr.length;
  for(let i=0; i<len; i++){
    for(let j=i+1; j<len; j++){
      if(arr[j-1] > arr[j]){
        [arr[j-1], arr[j]] = [arr[j], arr[j-1]]
      }
    }
  }
  return arr;
}
[2, 1, 3].bubleSort(); // [1, 2, 3]

 
 

js 实现:选择排序

Array.prototype.selectSort = function() {
  let arr = this,
    len = arr.length;
  for (let i = 0; i < len; i ++) {
    for (let j = i; j < len; j ++) {
      if (arr[i] > arr[j]) {
        [arr[i], arr[j]] = [arr[j], arr[i]];
      }
    }
  }
  return arr;
}
[1, 3, 2, 4].selectSort(); // [1, 2, 3, 4]

 
 

记录四:最大值

Math.max(...[1, 2, 3, 4]); // 4
Math.max.apply(this, [1, 2, 3, 4]); // 4
[1, 2, 3, 4].reduce((prev, cur, curIndex, arr) => {
	return Math.max(prev, cur);
}); // 4

 
 

记录五:求和

[1, 2, 3, 4].reduce((prev, cur, curIndex, arr) => {
	return prev + cur;
}, 0); // 10

 
 

记录六:合并

var a = [1, 2, 3, 4];
var b = [5, 6];
a.concat(b); // [1, 2, 3, 4, 5, 6]
[...a, ...b]; // [1, 2, 3, 4, 5, 6]
[].push.apply(a, b); // [1, 2, 3, 4, 5, 6]
b.map(item => {
	a.push(item);
}); // [1, 2, 3, 4, 5, 6]

 
 

记录七:判断是否包含

[1, 2, 3].includes(4); // false
[1, 2, 3].indexOf(4); // -1 表示没有
[1, 2, 3].find(item => item === 3); // 3 如果没有返回 undefined
[1, 2, 3].findIndex(item => item === 3); // 2 如果没有则返回 -1

 
 

includes(), find(), findIndex() 是 ES6 的 api。

记录八:类数组转换
类数组:表示有 length 属性,但是不具备数组的方法。

Array.prototype.slice.call(arguments); // arguments 是类数组(伪数组)
Array.prototype.slice.apply(arguments);
Array.from(arguments);
[...arguments];
// 可运行示例
function a () {
return [...arguments];
}
a(1, 2); // array
Array.from({ length: 9 }, () => 0); // [0, 0, 0, 0, 0, 0, 0, 0, 0]
// document.querySelectorAll('.color'); 返回的也是类数组
var targets = document.querySelectorAll('.color');
[].forEach.apply(targets, function(item){
	// do something.
});
// slice 实现
Array.prototype.slice = function(start, end) {
  var result = new Array();
  start = start || 0;
  end = end || this.length;
  for(var i = start; i < end; i ++){
    result.push(this[i]);
  }
  return result;
}

 
 
  1. call、apply:改变 slice 里面的 this 指向 arguments, 所以 arguments 也可以调用数组的方法。
  2. Array.from: 将类数组或可迭代对象创建为数组。
  3. … 将数组扩展为字符串,再定义为数组。

记录九:每项设置值

[1, 2, 3].fill(false); // [false, false, false]
Array.from({ length: 9 }, () => 0); // [0, 0, 0, 0, 0, 0, 0, 0, 0]

 
 

fill 是 ES6 的方法。

记录十:单项处理

// every 每项都满足返回 true
[1, 2, 3].every(item => { return item > 2 }); // false
// 有一项满足返回 true
[1, 2, 3].some(item => { return item > 2 }); // true
// 数组过滤
[1, 2, 3].filter(item => { return item > 2 }); // [3]

 
 

some、every、filter 是 ES5 的 api。

记录十一:对象、数组转化

1.Object.keys({name: 'zhangsan', age: 14}); // ["name", "age"]
2.Object.values({name: 'zhangsan', age: 14}); // ["zhangsan", 14]
3.Object.entries(["zhangsan", 14]); // [["name", "zhangsan"], ["age", 14]]
4.Object.fromEntries(["name", "zhangsan"], ["age", 14]); // ES10 的 api,Chrome 不支持,firebox 输出 { "name": "张三", "age": 14 }

至此,结束。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值