【问题标题】:How to dynamically populate an array using a for in loop如何使用 for in 循环动态填充数组
【发布时间】:2015-07-31 15:21:18
【问题描述】:

要返回一个数组 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);

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

更新

我怀疑我缺少的一点是设置set.length 不会将元素添加到数组中,它只会创建一个稀疏数组(一个有间隙的数组)。在我的情况下,您不能使用for in,因为没有任何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);

【问题讨论】:

  • 你不能那样增加数组的大小。

标签: javascript arrays for-in-loop


【解决方案1】:

在我看来,您想创建一个包含动态内容的静态大小的数组。如果是这种情况,您需要首先创建具有适当大小的数组。那将为您创建数组。但是,您可以使用所需的随机值自动填充数组,如下所示:

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]

这是我得到这个的地方:Create a JavaScript array containing 1...N

【讨论】:

  • 您的链接是我找到当前困境的答案的地方(Niko Ruotsalainen 使用 spread 发布)。谢谢!
【解决方案2】:

它返回未定义,因为您使用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]

【讨论】:

  • 从技术上讲,“数组的所有元素都是undefined”是不正确的:事实上,数组没有元素,这可以通过使用Object.getOwnPropertyNames(set) 来确定。见my answer
【解决方案3】:

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);

【讨论】:

    【解决方案4】:

    问题不在于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!
    

    您正在做的是创建一个包含零元素的数组,然后将其扩展为包含 50 个“孔”,就像有两个孔的数组一样。由于此数组没有可枚举的属性(length 不可枚举),因此您无法使用 for...in 对其进行迭代。最终,您最好使用传统的 for 循环。

    编辑

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

    属性引用返回 undefined 有两种方式:属性不存在或属性存在且包含值 undefined。因此:

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

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

    【讨论】:

    • 未定义与孔有何不同,为什么在我的示例中访问set[2] 时返回未定义?
    • @jeanpier_re 查看我的编辑。简而言之,set[2] 返回 undefined,因为 2 不作为 set 的属性存在。
    【解决方案5】:

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

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

    【讨论】:

      【解决方案6】:

      用填充值填充数组的最佳和最简单的方法可以简单地通过实例化 Array() 类然后使用 Array.protype.fill() 方法为其赋予值来完成。

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

      进一步参考,可以阅读以下article

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2014-04-09
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2020-09-14
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多