数组去重
1. 双重循环比较
function remove(arr) {
var newArr = []
for (var i = 0; i < arr.length; i++) {
for (var j = i + 1; j < arr.length; j++) {
if (arr[i] === arr[j]) {
i++
j = i
}
}
newArr.push(arr[i])
}
return newArr;
}
2.遍历数组+indexOf
var arr = [2, 8, 5, 0, 5, 2, 6, 7, 2]
function remove(arr) {
var newArr = []
for (var i = 0; i < arr.length; i++) {
// indexOf()方法如果查询到则返回查询到的第一个结果在数组中的索引,如果查询不到则返回-1
if (newArr.indexOf(arr[i]) === -1) {
newArr.push(arr[i])
}
}
return newArr;
}
console.log(remove(arr)) // 结果:[2, 8, 5, 0, 6, 7]
3.数组下标判断法
如果在arr数组里面找当前的值,返回的索引等于当前的循环里面的i的话,那么证明这个值是第一次出现,所以推入到新数组里面,如果后面又遍历到了一个出现过的值,那也不会返回它的索引。
function remove(arr) {
var newArr = []
for (var i = 0; i < arr.length; i++) {
if (arr.indexOf(arr[i]) === i) {
newArr.push(arr[i])
}
}
return newArr;
}
4. 排序后相邻比较去除法
function remove(arr) {
arr.sort(); // 先排序,遍历按顺序比较
var newArr = [arr[0]] // 初始化arr[0]
for (var i = 1; i < arr.length; i++) {
if (arr[i] !== newArr[newArr.length - 1]) {
newArr.push(arr[i])
}
}
return newArr;
}
数组扁平化方法
数组扁平化概念:数组扁平化是指将一个多维数组降维成一维数组:
[1, [2, 3, [4, 5]]] ------> [1, 2, 3, 4, 5]
1.遍历数组+递归
基本思路:遍历数组,如果数组中还有数组的话,递归调用flatten扁平函数,用concat连接,返回结果。
let arr = [1, [2, 3, [4, 5]]];
const flatten = (arr) => {
let res = [];
for(const item of arr) {
if(Array.isArray(item)) {
res = res.concat(flatten(item)); // 递归调用flatten扁平函数
} else {
res.push(item);
}
}
return res;
}
console.log(flatten(arr)); // [ 1, 2, 3, 4, 5 ]
2.迭代方法
function flatten2(arr) {
const queue = [...arr]; // 用队列实现
const res = [];
while (queue.length) {
const next = queue.shift(); // 从队列里取出
if (Array.isArray(next)) {
queue.push(...next); // 把next扁平化,然后放入queue中
} else {
res.push(next);
}
}
return res;
}
function flatten2(arr) {
const stack = [...arr];
const res = [];
while (stack.length) {
const next = stack.pop(); // 从栈里取出
if (Array.isArray(next)) {
stack.push(...next); // 把next扁平化,然后放入stack中
} else {
res.push(next);
}
}
return res.reverse(); // 翻转一下顺序
}
基本思想就是,先把arr中的东西都放入stack中,然后不停pop stack中的东西。如果pop出来的是一个数组,那么把数组扁平化,再放入stack中;如果pop出来的不是数组,那么放入res中。
3.reduce方法
实现思路:使用reduce进行归并,如果数组中还有数组的话,递归调用flatten扁平函数。用concat连接,返回结果。
const flatten = (arr) => {
return arr.reduce((res, item) => {
return res.concat(Array.isArray(item) ? flatten(item) : item);
},[]);
}
console.log(flatten(arr)); //[ 1, 2, 3, 4, 5 ]
reduce方法会迭代数组的所有项,并在此基础上构建一个最终返回值。该方法接收两个参数:对每一项都会运行的归并函数(回调函数),以及可选的并以之为归并起点的初始值。
// 例:求数组的各项值相加的和
let sum = arr.reduce((prev, cur)=> {
return prev + cur;
},0);
4.toString()+split()
调用数组的toString()方法,将数组变成字符串然后再用split()分割还原为数组。split()方法会根据传入的分隔符将字符串拆分成数组。
const flatten = (arr) => {
return arr.toString().split(',').map(item => {
return parseInt(item);
})
}
console.log(flatten(arr)); // [ 1, 2, 3, 4, 5 ]
因为split分割后形成的数组(["1", "2", "3", "4", "5"])的每一项值为字符串,所以用map方法遍历数组将其每一项转换为数值类型。
5.join()+split()
和上面的toString()一样,join()也可以将数组转换为字符串。
const flatten = (arr) => {
return arr.join(',').split(',').map(item => {
return parseInt(item);
})
}
console.log(flatten(arr));
6.展开运算符
ES6中对象中的扩展运算符(...)用于取出参数对象中的所有可遍历属性,拷贝到当前对象之中。这里参数对象是个数组,数组里面的所有对象都是基础数据类型,将所有基础数据类型重新拷贝到新的数组中。
let array = [1,2,3,4];
let copy = [...array]; //可以用展开运算符赋值数组
console.log(copy); // [ 1, 2, 3, 4 ]
var arr = [1,[2,3],[4,5]];
let res = [].concat(...arr); //利用扩展运算符将二维数组变为一维
console.log(res); // [ 1, 2, 3, 4, 5 ]
根据以上结果的启发,如果arr中含有数组则使用一次展开运算符,逐层击破,用concat连接,返回最终结果。
function flatten(arr){
while(arr.some(item => Array.isArray(item))){
arr = [].concat(...arr);
// [ 1, [ 2, 3, [ 4, 5 ] ] ]
// [ 1, 2, 3, [ 4, 5 ] ]
// [ 1, 2, 3, 4, 5 ]
}
return arr;
}
console.log(flatten(arr)); // [ 1, 2, 3, 4, 5 ]
本文参考:js5种方法实现数组扁平化