兄弟萌,快来学一下JS 快速声明数组,并填充元素

1,526 阅读2分钟

标题党一下,刷 leetcode 时声明数组的遇到一个 bug,想着整理出来分享一下,避免大家也踩坑。

在我们日常开发中,常常需要快速声明数组,那怎么样可以又快又骚的实现呢?

举一个实际的 🌰:

JavaScript 怎么快速声明一个数组,长度为 100,元素全是 0?

先来一个正常实现的版本吧。

for 循环

let arr = new Array(100)
for (let i = 0; i < 100; i++) {
  arr[i] = 0
}

虽然这样可以达到效果,但是代码写起来居然有3 行!看起来一点也不简洁。

map

map() 方法创建一个新数组,其结果是该数组中的每个元素都调用一个提供的函数后返回的结果。

let arr = new Array(100).map(v=>0)
// (100) [empty × 100]

what?数组怎么还是空的,怎么和想要的结果不一致,找找原因。

仔细看看文档发现 map 调用的数组是离散的,新数组将也是离散的保持相同的索引为空。换句人话就是 map 不会对空数组进行检测

怎么办?改造一下数组吧。

let arr = [...new Array(100)].map(v=>0)

终于简洁了,但是不太好记忆搞不好就忘了 map 不会对空数组进行检测写出第一种了。

fill

fill() 方法用一个固定值填充一个数组中从起始索引到终止索引内的全部元素。不包括终止索引。

let arr = new Array(100).fill(0)

666 貌似解决了,我们看一个 🌰:

let arr = new Array(2).fill(new Set())

for (let i in arr){
  arr[i].add(i)
}
// [Set(2) {"0", "1"} ,Set(2) {"0", "1"}]

咋回事,怎么两个数组元素共享内存了,再看看文档发现:

当一个对象被传递给 fill方法的时候, 填充数组的是这个对象的引用

怪不得,看来 fill 方法只能快速声明基本类型数据了。

from

Array.from() 方法从一个类似数组或可迭代对象创建一个新的,浅拷贝的数组实例。

先来看看基本类型:

let arr = Array.from(new Array(100),v=>0)

再来试试对象吧:

let arr = Array.from(new Array(2),v=>new Set())
for (let i in arr){
  arr[i].add(i)
}
// [Set(1) {"0"} ,Set(1) {"1"}]

完美完美,终于找到简洁完美的方法了!

总结

  • 如果填充数据是基本数据类型,推荐使用 fill 方法
  • 如果填充数据是对象,推荐使用 from 方法