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