如何使用for in循环动态填充数组

How to dynamically populate an array using a for in loop

本文关键字:动态 填充 数组 循环 in 何使用 for      更新时间:2023-09-26

返回一个数组set与1和500之间的随机数序列,我试图重构一个循环for(var i = 0; i< 50; i++)的标准,这是有效的,但当我试图做一个重构使用for in循环它没有。我猜是关于array.length的属性和它的用途,我搞砸了。

TL;DR为什么返回一个包含50个未定义元素的数组,而不是一个包含50个随机整数的数组?有没有一种方法可以让这种方法奏效呢?

var set = [];
set.length = 50;
for(var i in set){
    set[i] = Math.floor((Math.random() * 500) + 1);
}
console.log(set);

类似问题:很有帮助,但不是我想要的

  • 在JavaScript中循环数组
  • 为什么使用"for…数组迭代是个坏主意吗?
<标题> 更新

我怀疑我错过的一点是设置set.length不会向数组添加元素,它只会创建一个稀疏数组(一个有间隙的数组)。在我的情况下,您不能使用for in,因为在数组中没有任何可以迭代。我要么必须用虚拟内容填充数组(即;空字符串),或者更合乎逻辑地,将我试图用.length属性实现的范围部分分离为单独的range变量。

工作版本

var set = [], range = 50;
for(var i = 0; i < range; i++){
    set[i]=Math.floor((Math.random() * 500) + 1);
}
console.log(set);

返回undefined,因为您正在使用set.length设置数组长度。当调用这个函数时,数组的所有元素都是undefined

我将完全删除set.length行。

更新代码
var set = [];
for (i = 0; i <= 50; i++) {
  set.push(Math.floor(Math.random() * 500))
}
console.log(set)
=> [138, 215, 149, 180, 348, 497, 88, 156, 238, 439, 130, 185, 20, 116, 330, 131, 188, 257,
    260, 1, 469, 482, 208, 494, 26, 374, 281, 403, 403, 137, 156, 243, 378, 281, 329,
    84, 471, 429, 120, 381, 456, 471, 36, 395, 299, 497, 151, 210, 80, 310]

这听起来像你想创建一个静态大小的数组与动态内容。如果是这种情况,您需要首先创建具有适当大小的数组。这会为你创建数组。但是,您可以使用所需的随机值自动填充数组,如下所示:

var N = 50;
var set = Array.apply(null, {length: N}).map(Function.call, Math.random);
一旦数组被自动填充,剩下的代码应该像预期的那样工作,只需使用数组中的随机数的值:
for(var i in set){
    set[i] = Math.floor(set[i] * 500) + 1;
}
console.log(set);
// OUTPUT
// [267, 219, 293, 298, 403, 70, 162, 270, 434, 292, 433, 478, 476, 
//  311, 268, 266, 105, 242, 255, 250, 206, 104, 142, 406, 50, 139, 
//  364, 375, 47, 480, 445, 149, 91, 228, 404, 267, 298, 158, 305, 
//  311, 92, 377, 490, 65, 149, 431, 28, 452, 353, 494]
创建一个JavaScript数组,包含1…N

for in似乎不是您想要的。试试for循环:

var set = [], 
    i = 0, 
    l = null;
set.length = 50;
for(; l = set.length; i < l; i++){
    set[i] = Math.floor((Math.random() * 500) + 1);
}
console.log(set);

问题不在于array.length属性,而是这种扩大数组的方法不创建"属性"。注意:

> [ /*hole*/ , /*hole*/ ,] // An array with two "holes"
[ ,  ]
> new Array(2) // Another way to create an array with two holes
[ ,  ]
> [ undefined, undefined ] // An array with two undefined elements -- not the same
[ undefined, undefined ]
> Object.getOwnPropertyNames([undefined, undefined]);
[ '0', '1', 'length' ]
> Object.getOwnPropertyNames([,,]);
[ 'length' ] // Doesn't have any integer properties!

你所做的是创建一个包含0个元素的数组,然后将其扩展为包含50个"孔",就像有两个孔的数组一样。因为这个数组没有可枚举的属性(length不是可枚举的),你不能使用for...in来迭代它。最终,您最好使用传统的for循环。

编辑

我能想到的"洞"的最佳定义是一个不存在的数组属性,其名称为整数i,因此0 <= i && i < array.length .(考虑到这一点,重要的是要注意JavaScript数组只是具有称为"索引"的数字属性的对象和一些额外的特殊功能。)

属性引用有两种返回undefined的方式:要么该属性不存在,要么该属性存在且包含undefined值。因此:

> myObject = { myProp: 1, otherProp: undefined }
{ myProp: 1, otherProp: undefined }
> myObject.nonExistentProperty
undefined
> myObject.otherProp
undefined

现在,hole是一个不存在的属性,就像上面的myObject.nonExistentProperty一样,所以尝试访问它将导致它返回undefined

第二个链接似乎有你的答案。

for (var item in array)查看您的数组,并且对于数组中的每个项,将该项存储在"item"中,并允许您迭代每个项。设置阵列。length不会给您数组中的任何项,因此for in根本不会执行-没有什么可迭代的

用填充值填充数组的最好和最简单的方法可以简单地通过实例化Array()类,然后使用Array.protype.fill()方法来给它赋值。

const array_filler = new Array(10).fill(20)

要进一步参考,您可以阅读以下文章

老问题,但因为我正在寻找一个简短的方法来做到这一点,我最终想出了这个方法:

[...Array(50)].map(e => Math.floor((Math.random() * 500) + 1))

如果你想从1-50中得到一个数字列表,你可以使用map的第二个参数:

[...Array(50)].map((e, i) => i + 1)

最后,如果你已经有了一个返回值的函数,你可以简单地调用它:

[...Array(50)].map(Math.random)