数组的扁平化,去重,排序

将数组扁平化去并除其中重复部分数据,最终得到一个升序且不重复的数组

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