JS数组方法 flat(),flatMap() - Kaiqisan

JS数组方法 flat(),flatMap()

ヤッハロー、Kaiqisanすうう、一つふつうの学生プログラマである。这一节是我最后的一个数组方法的专题,是之前的遗漏的东西,今天把它彻底讲完,然后皆大欢喜。

flat(val):高维数组降维操作,它不会修改原数组的,会有返回值,需要参数来接收,内有参数val,代表需要下降的维数,例如val=3,Arr数组维数为5那么,这个操作就会使五维数组降到二维数组,如果val值过大,也不会报错,最多降到一维数组之后就不会再进行操作。val值可选,如果不填,就是默认值1。也可以传入Infinity(一种数据类型为number的数字,代表无穷大∞,不管怎么操作结果都是Infinity或-Infinity),直接变成一维数组。

let arr = [1, 2, 3, ['a', 'b']]
console.log(arr.flat()) // [1, 2, 3, "a", "b"]

偏复杂的情况

let arr = [1, 2, 3, ['a', 'b', [10, 20, ['ee', 'gg']], 'd', 'fff']]
console.log(arr.flat(2)) // [1, 2, 3, 'a', 'b', 10, 20, ['ee', 'gg'], 'd', 'fff']

比较特殊的情况

let arr = [1, 2, 3, ['a', 'b', [10, 20, ['ee', 'gg']], 'd', 'fff']]
console.log(arr.flat(Infinity)) // [1, 2, 3, 'a', 'b', 10, 20, 'ee', 'gg', 'd', 'fff']

很复杂的情况

let arr = [1, 2, 3, 'a', 'b', ['d', [45, 7878], 'e', [4, 8, ['sdsd', 'asidhasi'], 78]]]
console.log(arr.flat(2))
// [1, 2, 3, 'a', 'b', 'd', 45, 7878, 'e', 4, 8, ['sdsd', 'asidhasi'], 78]

很明显,它们有一个共同的特点,也是flat方法的机制,就是先去掉外面的那层“”,从外到内一层一层剥开。

下面,我手写一个flat方法,然后开始讲解它的原理

function imitateFlat(arr) {
    let res = [] // 最后输出带出的数组
	res = exeImitateFlat(arr, [])
	return res
}

function exeImitateFlat(arr, res) {
    for (let i = 0; i < arr.length; i++) {
	    if (Array.isArray(arr[i])){
	        exeImitateFlat(arr[i], res)
		} else {
	        res.push(arr[i])
		}
	}
	return res
}

let arr = [1, 2, 3, ['a', 'b', [10, 20, ['ee', 'gg']], 'd', 'fff']]
console.log(imitateFlat(arr))
// 输出为 [1, 2, 3, 'a', 'b', 10, 20, 'ee', 'gg', 'd', 'fff']

这个方法把所有高维数组全部变成一维数组,相当于arr.flat(Infinity)

下面的代码健壮性更加强

// num代表降维选择,相当于flat方法里传入的参数,如果没有传值,默认为1
function imitateFlat(arr, num = 1) {
	return this.exeImitateFlat(arr, num, [])
}

function exeImitateFlat(arr, res) {
    let temp = num
   	for (let i = 0; i < arr.length; i++) {
   	    if (Array.isArray(arr[i])) {
   	        if (num > 0) {
   	            temp-- // temp减一,深入到内部的数组
   	            exeImitateFlat(arr[i], temp, res)
				temp++	// 内部数组遍历完成,恢复temp的值,继续在当前层遍历
   	            continue
   	        }
   	    }
   	    res.push(arr[i])
   	}
   	return res
}

let arr = [1, 2, 3, ['a', 'b', [10, 20, ['ee', 'gg']], 'd', 'fff']]
console.log(imitateFlat(arr, 2))
// 输出为 [1, 2, 3, 'a', 'b', 10, 20, ['ee', 'gg'], 'd', 'fff']

flatMap(callback, thisArg): 很像map方法的一个方法,第一个参数为回调函数,第二个参数为希望传入回调函数的并作为回调函数内部this参数书写的参数。

let arr = [10, 20, 30, 50, 40]
let a = arr.flatMap(x => {
    return [[x]]
})
console.log(a); // [[10], [20], [30], [50], [40]]

它和map方法不同的就是它可以为参数嵌套数组层数(维度),且输入数组和输出数组并不是一对一的关系了,输入数组有n个成员,输出数组可以有不同于n个数量的成员。

let arr = [10, 20, 30, 50, 40]
let a = arr.flatMap(x => {
    return [[x], 10]
})
console.log(a); // [[10], 10, [20], 10, [30], 10, [50], 10, [40], 10]

总结

上面的那个手写flat方法是我自己纯手写的,改bug改了好久,我居然把temp++,恢复操作遗漏了,感觉自己上学期的数据结构白学了,自己的算法能力还是很菜。说真的,学前端之前可以先学学算法,这样学起js来会更加轻松。

  • 3
    点赞
  • 12
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 3
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

kaiqisan

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

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

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

打赏作者

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

抵扣说明:

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

余额充值