數組的扁平化,去重,排序
將數組扁平化去併除其中重複部分數據,最終得到一個升序且不重複的數組
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