flat与flatMap 数组浅扁平化 深扁平化 手写myFlat myFlatMap

flat

Array.prototype.flat
扁平化 多维数组 -> 一维数组

const arr = [0, 1, [2, 3], 4, 5];
const newArr = arr.flat();

console.log(newArr);//[0, 1, 2, 3, 4, 5]

返回一个新的数组
将二维数组转化为一维数组

const arr = [0, 1, [2, 3], 4, 5];
const newArr = arr.flat();

console.log(arr === newArr);//false

flat默认情况下参数是1 -> 向内深入一层

const arr = [0, 1, [2, [3, 4], 5], 6];

const newArr = arr.flat();
console.log(newArr);

在这里插入图片描述

参数

结构深度
默认为1 向数组内部深入一层 变成两层
flat默认情况下是浅的扁平化

参数 正无穷 Infinity 结构深度无穷大的设置

const arr = [0, [1, 2, [3, 4, [5, 6, [7, 8, [9]]]]]];
const newArr = arr.flat(Infinity);
console.log(newArr);//[0, 1, 2, 3, 4, 5, 6, 7, 8, 9]

当参数为负数的时候 不做任何扁平化处理

const arr = [0, 1, [2, [3, 4], 5], 6];

const newArr = arr.flat(-2);
console.log(newArr);

在这里插入图片描述
字母字符串也不做处理

const arr = [0, 1, [2, [3, 4], 5], 6];

const newArr = arr.flat('a');
console.log(newArr);

在这里插入图片描述
数字字符串 -> Number -> 数字类型

const arr = [0, 1, [2, [3, 4], 5], 6];

const newArr = arr.flat('2');
console.log(newArr);//[0, 1, 2, 3, 4, 5, 6]

当为0时 也不做任何处理

const arr = [0, 1, [2, [3, 4], 5], 6];

const newArr = arr.flat(0);
console.log(newArr);

在这里插入图片描述

true / fasle 都要经过Number转化为数字类型在处理

对于稀松数组

剔除所有的数组空隙empty

const arr = [1, , [2, , [3, 4, , 5, , , 6, [7, , , 8, 9, , [0]]]]];

const newArr = arr.flat(Infinity);
console.log(newArr);

在这里插入图片描述

浅扁平化实现

concat 是可以放入多个数组元素或者其他数组

var a = 1,
  b = [2, 3],
  c = [3, 4];
const newArr = b.concat(a, c);

console.log(newArr);//[2, 3, 1, 3, 4]

1.用reduce实现

function shallowFlat(arr) {
  return arr.reduce(function (prev, current) {
    return prev.concat(current);
  }, []);
}

2.ES6展开运算符

function shallowFlat(arr) {
  return [].concat(...arr);
}

深扁平化

reduce + concat + isArray + 递归

Array.prototype.deepFlat = function () {
  var arr = this,
    deep = arguments[0] !== Infinity ? arguments[0] >>> 0 : Infinity;
  return deep > 0
    ? arr.reduce(function (prev, current) {
        return prev.concat(Array.isArray(current) ? current.deepFlat(deep - 1) : current);
      }, [])
    : arr;
};

forEach + isArray + push + 递归

Array.prototype.deepFlat = function () {
  var arr = this,
    deep = arguments[0] !== Infinity ? arguments[0] >>> 0 : Infinity,
    res = [];
  (function _() {
    arr.forEach(function (item) {
      if (Array.isArray(item) && deep > 0) {
        _(item, deep - 1);
      } else {
        res.push(item);
      }
    });
  })(arr, deep);
  return res;
};

for of + isArray + push 去掉empty

Array.prototype.deepFlat = function(){
	var arr = this,
	deep = arguments[0] !== Infinity ? arguments[0] >>> 0 : Infinity,
	res = [];
	(function _(arr,deep){
		for(var item of arr){
			if(Array.isArray(item) && deep > 0){
				_(item,deep - 1)
			}else{
				//判断是否时empty 用void 0
				item !== void 0 && res.push(item)
			}
		}		
	})(arr,deep)
	return res
}

用栈 + 展开运算符 vue 用过的方法

Array.prototype.deepFlat = function () {
  var arr = this,
    stack = [...arr],
    res = [];
  while (stack.length) {
    const popItem = stack.pop();
    console.log(stack);
    if (Array.isArray(popItem)) {
      stack.push(...popItem);
    } else {
      popItem !== void 0 && res.push(popItem);
    }
  }
  return res.reverse();
};

纯递归

Array.prototype.deepFlat = function () {
  var arr = this,
    res = [];
  (function _(arr) {
    arr.forEach(function (item) {
      if (Array.isArray(item)) {
        _(item);
      } else {
        res.push(item);
      }
    });
  })(arr);
  return res;
};

生成器函数

function* deepFlat(arr) {
  for (var item of arr) {
    if (Array.isArray(item)) {
      yield* deepFlat(item);
    } else {
      yield item;
    }
  }
}

数组扁平化后数组去重并升序排列

原始写法

      var arr = [[1, 2, 2], [3, 4, 5, 5], [6, 7, 8, 9, [11, 12, [12, 13, [14]]]], 10];
      function flatten(arr) {
        var _arr = arr || [],
          fArr = [],
          len = _arr.length,
          item;
        for (var i = 0; i < len; i++) {
          item = _arr[i];
          if (_isArr(item)) {
            fArr = fArr.concat(flatten(item));
          } else {
            fArr.push(item);
          }
        }
        return fArr;
        function _isArr(item) {
          return {}.toString.call(item) === '[object Array]';
        }
      }
      console.log(flatten(arr));// [1, 2, 2, 3, 4, 5, 5, 6, 7, 8, 9, 11, 12, 12, 13, 14, 10]

挂载到原型上

      Array.prototype.flatten = function () {
        var _arr = this,
          toStr = {}.toString;
        if (toStr.call(_arr) !== '[object Array]') {
          throw new Error('只有数组才能调用flatten方法');
        }
        var fArr = [];
        return _arr.reduce(function (prev, item) {
          return prev.concat(toStr.call(item) === '[object Array]' ? item.flatten() : item);
        }, []);
      };
      console.log(arr.flatten());
      Array.prototype.flatten = function () {
        var _arr = this,
          toStr = {}.toString;
        if (toStr.call(_arr) !== '[object Array]') {
          throw new Error('只有数组才能调用flatten方法');
        }
        var fArr = [];
        _arr.forEach(function (item) {
          toStr.call(item) === '[object Array]'
            ? (fArr = fArr.concat(item.flatten()))
            : fArr.push(item);
        });
        return fArr;
      };
      console.log(arr.flatten());

ES6 箭头函数写法

      const flatten = (arr) =>
        arr.reduce((prev, item) => {
          return prev.concat({}.toString.call(item) === '[object Array]' ? flatten(item) : item);
        }, []);
      console.log(flatten(arr));

flatMap

Array.prototype.flatMap
flat + map
遍历 + 扁平化

const arr = ['123', '456', '789'];
const newArr = arr.flatMap(function (item) {
  return item.split('');
});
console.log(newArr);

在这里插入图片描述

返回一个新的数组

const arr = ['123', '456', '789'];
const newArr = arr.flatMap(function (item) {
  return item.split('');
});
console.log(newArr === arr); //false

回调参数

当前遍历的元素 当前遍历元素在数组中对应的下标 数组本身

const arr = ['123', '456', '789'];

const newArr = arr.flatMap(function (item, index, arr) {
  console.log(item, index, arr);
});

在这里插入图片描述
回调中this默认指向window

const arr = ['123', '456', '789'];

const newArr = arr.flatMap(function (item, index, arr) {
  console.log(this);
});

在这里插入图片描述
严格模式下 this为undefined

'use strict';
const arr = ['123', '456', '789'];

const newArr = arr.flatMap(function (item, index, arr) {
  console.log(this);
});

在这里插入图片描述

第二个参数

改变回调内this的指向

const arr = ['123', '456', '789'];

const newArr = arr.flatMap(
  function (item, index, arr) {
    console.log(this);
  },
  { a: 1 }
);

在这里插入图片描述

实例

对字符串进行分段处理 并生成新的数组

const arr = ["My name's kobe", "I'm 35", 'years old.'];

const newArr = arr.flatMap(function (item) {
  return item.split(' ');
});
console.log(newArr);

在这里插入图片描述

对数组进行遍历的过程中进行某些运算 并添加回数组中

const arr = [1, -2, -3, 5, 8, -9, 6, 7, 0];

const newArr = arr.flatMap(function (item, index) {
  if (item < 0 && index >= 1) {
    return [item, `${item} + ${arr[index - 1]} = ${item + arr[index - 1]}`];
  }
  return item;
});

console.log(newArr);

在这里插入图片描述

重写myFlatMap

Array.prototype.myFlatMap = function () {
  if (typeof cb !== 'function') {
    throw new TypeError('Callback must be a function');
  }
  var arr = this,
    arg2 = arguments[1],
    res = [];
  for (var i = 0; i < arr.length; i++) {
    item = cb.apply(arg2, [arr[i], i, arr]);
    item && res.push(item);
  }
  return res.flat();
};
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

_聪明勇敢有力气

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值