数组的扁平化,去重,排序
将数组扁平化去并除其中重复部分数据,最终得到一个升序且不重复的数组
var arr = [ [1, 2, 2], [3, 4, 5, 5, '5' ], [6, 7, 8, 9, [11, 12, [12, 13, [14] ] ] ], 10];
1.es6解法
优点:语法简洁,代码量小
缺点:晦涩难懂,兼容性是个大问题
Array.from(new Set(arr.flat(Infinity))).sort((a,b)=>{ return a-b})
// [1, 2, 3, 4, 5, "5", 6, 7, 8, 9, 10, 11, 12, 13, 14]
// 语法解析
// 打平数组方法
// Array.prototype.flat(Infinity)
// flat为es6新增打平数组方法 Infinity是打平层数
// 其他比较好的方法一
const flatArray = arr => arr.reduce((a,b) => a.concat(Array.isArray(b) ? flatArray(b): b), []);
flatArray(arr)
// [1, 2, 2, 3, 4, 5, 5, "5", 6, 7, 8, 9, 11, 12, 12, 13, 14, 10]
// es5写法便于理解
// const flatArray = function(arr) {
// return arr.reduce(function(a, b) {
// return a.concat(Array.isArray(b) ? flatArray(b) : b);
// }, []);
// };
// 重点解析Array.prototype.reduce() 这个方法,参考mdn
// arr.reduce(callback(accumulator, currentValue[, index[, array]])[, initialValue])
// reduce 方法接受两个参数,第一个是callback,第二个initialValue是初始值,没有的话使用数组第一个元素
// callback 接受四个参数
// accumulator
// 累计器累计回调的返回值; 它是上一次调用回调时返回的累积值,或initialValue。
// currentValue
// 数组中正在处理的元素。
// currentIndex可选
// 数组中正在处理的当前元素的索引。 如果提供了initialValue,则起始索引号为0,否则为1。
// array可选
// 调用reduce()的数组
var array=[0,1,2,3,4]
array.reduce((a,b)=>a+b,[])
// [] + 0 ="0"
// "01234"
array.reduce((a,b)=>a+b,"")
// "01234"
array.reduce((a,b)=>a+b)
// 10
// 其他比较好的方法二
Array.prototype.customFlat= function() {
return [].concat(...this.map(item => (Array.isArray(item) ? item.customFlat() : [item])));
}
arr.customFlat()
// [1, 2, 2, 3, 4, 5, 5, "5", 6, 7, 8, 9, 11, 12, 12, 13, 14, 10]
// new Set()
// Set为es6新增数据结构,元素唯一,接受一个数组作为参数
// Array.from()
// Array.from()是es6将类数组转换成数组的方法
// Array.prototype.sort()
// sort是es5的排序语法
2.es5解法
优点:易于理解,兼容性好
缺点:语法冗余,代码量大
打平数组
// 转成字符串方法
/*
arr.toLocaleString()及arr.join()和arr.toString()
一样所有数据都会转变成字符串型,保留不了原来的数据类型,
不建议使用,(不影响的也可以用,毕竟简洁)
*/
arr.toString()
// "1,2,2,3,4,5,5,5,6,7,8,9,11,12,12,13,14,10"
// 递归
var arr_ = [];
function customFlat(arr) {
arr.forEach(function(item){
Array.isArray(item) ? customFlat(item) : arr_.push(item);
});
return arr_;
}
console.log(customFlat(arr));
// [ 1, 2, 2, 3, 4, 5, 5, '5', 6, 7, 8, 9, 11, 12, 12, 13, 14, 10 ]
// 广度遍历
function flatten(arr) {
var res = [];
var stack = [].concat(arr);
while (stack.length) {
var item = stack.shift();
if (item instanceof Array) {
stack = stack.concat(item);
} else {
res.push(item);
}
}
return res;
}
console.log(flatten(arr));
// [ 10, 1, 2, 2, 3, 4, 5, 5, '5', 6, 7, 8, 9, 11, 12, 12, 13, 14 ]
数组去重
// 方法很多,大多原理基本一致,就是检测是否存在。对象属性法检测不了属性的数据类型
function unique(arr) {
var result = [];
arr.forEach(function(item) {
if (result.indexOf(item) === -1) {
result.push(item);
}
});
return result;
}
console.log(unique(flatten(arr))); // flatten方法见上
// [ 1, 2, 3, 4, 5, '5', 6, 7, 8, 9, 11, 12, 13, 14, 10 ]
数组排序
// 方法很多,这里用一个经典的冒泡排序
function bubbleSort_1(data) {
for (var i = 0; i < data.length; i++) {
for (var j = 0; j < data.length - i - 1; j++) {
if (data[j] > data[j + 1]) {
var tem = data[j];
data[j] = data[j + 1];
data[j + 1] = tem;
}
}
}
return data;
}
console.log(bubbleSort_1(unique(flatten(arr)))) // unique和flatten方法见上
// [ 1, 2, 3, 4, 5, '5', 6, 7, 8, 9, 10, 11, 12, 13, 14 ]
排序去重
// flatten方法见上
var result = flatten(arr).sort( function (a,b) {return a-b }).reduce(function(init, current) {
if(init.length === 0 || init[init.length-1] !== current) {
init.push(current);
}
return init;
}, []);
console.log(result);
// [ 1, 2, 3, 4, 5, '5', 6, 7, 8, 9, 10, 11, 12, 13, 14 ]
参考链接:
1.mdn Array.prototype.reduce()
2.https://github.com/Advanced-Frontend/Daily-Interview-Question/issues/8