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

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

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

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

发布了45 篇原创文章 · 获赞 32 · 访问量 6万+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章