数组降维

es6函数

  1. const flatten = x => x.flat(Infinity);
  2. var array = [1, 2, [3, 2], 3, [2, 4, 5, 2, [3, 4, 5]], 4, 5, 6, 7];
  3. console.log(flatten(array));

使用reducer递归遍历

  1. // es6 结构
  2. const flatten = x => x.reduce((pre, cur) => Array.isArray(cur) ? [...pre, ...flatten(cur)] : [...pre, cur], []);
  3. //es5 concat
  4. const flatten = x => x.reduce((pre, cur) => Array.isArray(cur) ? pre.concat(flatten(cur)) : pre.concat(cur), []);

数组字符串化

  1. // 缺点由于字符串化,结果数组的类型会变成字符串
  2. const flatten = x => x.join(',').split(',')

递归+push

  1. const flatten = x => {
  2. let ret = [];
  3. let toArr = (x) => {
  4. x.forEach((item) => {
  5. Array.isArray(item) ? toArr(item) : ret.push(item)
  6. })
  7. };
  8. toArr(x);
  9. return ret
  10. };

数组去重

  • 双城循环
  • 排序后去重
  • filter
  • Object
  • ES6 Set

    方法总结

  1. Set:使用类型转换先将数组转换为set,然后再将set转为数组。
    • 无法对{}[]去重
  2. 排序比较相邻元素:利用sort(),然后比较相邻元素是否相等
  3. 遍历+ 判断(下面的任意组合)
    • 外层遍历可以使用下面的方法。
      • reduce
      • filter
      • 数组循环 + 临时变量存储结果
      • 数组循环+ 删除原有数组对应元素
    • 判断遍历的当前元素是否已存在
      • 借助API直接判断数组内是否存在某个元素
        • indexOf:对NaN均会返回-1,对于引用类型会比较引用地址
        • includes:对于引用类型会比较引用地址
      • 借助Map、Object,然后判断是否已存在
        • Object属性:Object的key是字符串,为其添加属性的时候会调用其toString方法
          • 无法处理引用类型数据。因为会将其转为字符串。
          • 无法处理特殊字符串,(”1”,”NaN”,”true”,”null”,”undefined”)
        • Map:对于引用类型会比较引用地址。
      • 遍历数组+自定义比较逻辑
        • 遍历
        • 自定义比较逻辑
          • ===
            • 都为引用类型时,比较引用地址
            • 类型和值都要相同
            • NaN === NaN // false
          • ==
            • 都为引用类型时,比较引用地址
            • 类型不同先进性类型转换,在进行比较
            • NaN === NaN // false
          • 自定义两个元素的比较逻辑

            方法实现对比

  • 对于一般的数据类型(不涉及到引用类型的)直接用遍历+includes判断,或者借助于es6的Set。
  • 对于不含有NaN的一般的数据类型,也可以使用 遍历 + indexOf的方法判断。
  • 如果涉及到引用类型的去重,使用遍历+手动写比较函数来处理。

注意点

**

  • 注意去重是否要保持原数组不改动。
  • 注意NaN以及SymBol类型

具体实现

Set

  1. const arr = [1, 1, 'true', 'true', true, true, 15, 15, false, false, undefined, undefined, null, null, NaN, NaN, 'NaN', 0, 0, 'a', 'a', {}, {}];
  2. function unique (arr) {
  3. return Array.from(new Set(arr))
  4. }
  5. console.log(unique(arr));
  6. // [1, "true", true, 15, false, undefined, null, NaN, "NaN", 0, "a", {…}, {…}]

reduce+includes

  1. const arr = [1, 1, 'true', 'true', true, true, 15, 15, false, false, undefined, undefined, null, null, NaN, NaN, 'NaN', 0, 0, 'a', 'a', {}, {}];
  2. function unique(arr) {
  3. return arr.reduce((prev, cur) => prev.includes(cur) ? prev : [...prev, cur], []);
  4. }
  5. console.log(unique(arr));
  6. // [1, "true", true, 15, false, undefined, null, NaN, "NaN", 0, "a", {…}, {…}]

reduce+indexOf

  1. const arr = [1, 1, 'true', 'true', true, true, 15, 15, false, false, undefined, undefined, null, null, NaN, NaN, 'NaN', 0, 0, 'a', 'a', {}, {}];
  2. function unique(arr) {
  3. return arr.reduce((prev, cur) => prev.indexOf(cur) !== -1 ? prev : [...prev, cur], []);
  4. }
  5. console.log(unique(arr));
  6. // [1, "true", true, 15, false, undefined, null, NaN, NaN, "NaN", 0, "a", {…}, {…}]

filter+indexOf

  1. const arr = [1, 1, 'true', 'true', true, true, 15, 15, false, false, undefined, undefined, null, null, NaN, NaN, 'NaN', 0, 0, 'a', 'a', {}, {}];
  2. function unique(arr) {
  3. return arr.filter(function(item, index, arr) {
  4. //当前元素,在原始数组中的第一个索引==当前索引值,否则返回当前元素
  5. return arr.indexOf(item, 0) === index;
  6. });
  7. }
  8. console.log(unique(arr));
  9. // [1, "true", true, 15, false, undefined, null, "NaN", 0, "a", {…}, {…}]

实现数组的随机排序

  1. // (1)使用数组 sort 方法对数组元素随机排序,让 Math.random() 出来的数与 0.5 比较,如果大于就返回 1 交换位置,如果小于就返回 -1,不交换位置。
  2. function randomSort(a, b) {
  3. return Math.random() > 0.5 ? -1 : 1;
  4. }
  5. // 缺点:每个元素被派到新数组的位置不是随机的,原因是 sort() 方法是依次比较的。
  6. // (2)随机从原数组抽取一个元素,加入到新数组
  7. function randomSort(arr) {
  8. var result = [];
  9. while (arr.length > 0) {
  10. var randomIndex = Math.floor(Math.random() * arr.length);
  11. result.push(arr[randomIndex]);
  12. arr.splice(randomIndex, 1);
  13. }
  14. return result;
  15. }
  16. // (3)随机交换数组内的元素(洗牌算法类似)
  17. function randomSort(arr) {
  18. var index,
  19. randomIndex,
  20. temp,
  21. len = arr.length;
  22. for (index = 0; index < len; index++) {
  23. randomIndex = Math.floor(Math.random() * (len - index)) + index;
  24. temp = arr[index];
  25. arr[index] = arr[randomIndex];
  26. arr[randomIndex] = temp;
  27. }
  28. return arr;
  29. }
  30. // es6
  31. function randomSort(array) {
  32. let length = array.length;
  33. if (!Array.isArray(array) || length <= 1) return;
  34. for (let index = 0; index < length - 1; index++) {
  35. let randomIndex = Math.floor(Math.random() * (length - index)) + index;
  36. [array[index], array[randomIndex]] = [array[randomIndex], array[index]];
  37. }
  38. return array;
  39. }

详细资料可以参考: 《Fisher and Yates 的原始版》 《javascript 实现数组随机排序?》 《JavaScript 学习笔记:数组随机排序》