为什么我不能使用 _.map(new Array(n), Math.random) 创建一个随机数组
Why can't I create a random array using _.map(new Array(n), Math.random)?
我想制作一个介于 0 和 1 之间的随机数数组,所以我尝试了:
var randList = _.map(new Array(5), Math.random);
但是我没有获得我期望的随机元素列表,而是得到了:
console.log(JSON.stringify(randList));
"[null,null,null,null,null]"
为什么我得到一个空数组而不是随机数?
实际上,你会得到一个undefined
数组 - 传递给map
的函数甚至一次都不会触发。发生这种情况是因为使用构造函数创建的数组new Array(Number)
有点奇怪 - 即使它的长度设置正确,它实际上也没有0
、1
等属性:
var arr = Array(5);
console.log(arr.length); // 5
console.log('0' in arr); // false
这就是为什么,即使普通的旧for (var i = 0; i < arr.length; i++)
可以迭代这个数组,for (var i in arr)
也不起作用:
for (var i in arr) {
console.log(i); // won't be called even once!
}
我想,这与 Array.map 发生的情况(映射 _.map 时)的情况不太相似:
var newarr = arr.map(function(el) {
console.log(el); // nope, still nothing
});
console.log(newarr); // [undefined x 5]
那么创建这样一个数组的正确方法是什么?在这里:
var rightArr = Array.apply(0, Array(5)); // ah, the pure magic of apply!
// and here goes an array of randoms:
var randArr = rightArr.map(Math.random);
。但当然,在这种情况下,使用_.times
是要走的路。)
Array(length)
构造函数创建一个稀疏数组。也就是说,数组的长度设置为指定的参数,但不填充数组的元素。因此,map
方法不会循环访问这些"未填充"元素。例如,以下代码片段不会在控制台上生成任何输出:
var arr = new Array(5);
for(var x in arr) console.log(x);
但是请注意,像这样初始化数组将产生预期的结果:
console.log(_.map([0,0,0,0,0], Math.random));
当然,这不会扩展。如果您希望数组中的元素数量是可变的,我建议您改用 times
方法:
var randList = _(5).times(Math.random);
或
var randList = _.times(5, Math.random);
只是想在raina77ow的出色答案中添加一些测试用例。
事实上,新的 Array(5) 不会在 Array 对象中分配 5 个属性。
无论你使用下划线还是普通的javascript Array.prototype.map(当然是在体面的浏览器中)都没有关系。
以下是节点中的测试用例.js
new Array(2)只返回一个空对象(没有键),带有 2 个(一种假的)占位符
> var a = new Array(2);
> a;
[ , ]
> a.length;
2
> Object.keys(a);
[]
映射结果也是一个带有 2 个占位符的空对象(无键)
> var result = a.map(Math.random);
> result;
[ , ]
> result.length;
2
> Object.keys(result);
[]
为什么结果是一个长度为 2 的数组对象,即使什么也没做?
阅读 Array.prototype.map polyfill implmentation https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/map
地图结果创建为 var res = new Array(source_array_length);
此外,即使值undefined
,映射也适用于填充数组
> [undefined, undefined].map(Math.random);
[ 0.6572469582315534, 0.6343784828204662 ]
好的,让我们也测试稀疏数组,长度为 2,但它只包含一个键"1"。
> var a = []; a[1] = 'somthing';
> a;
[ , 'somthing' ]
> a.length
2
> Object.keys(a);
[ '1' ]
映射结果返回一个长度为 2 的数组,但只有一个键 '1',只触发一个 Math.random!
> var result = a.map(Math.random);
undefined
> result.length
2
> result
[ , 0.8090629687067121 ] // only one Math.random fired.
> Object.keys(result);
[ '1' ]
- 如何使一个Math.random数组元素比另一个数组元素更有可能被选中
- Math.random不断返回相同的答案
- JS:如何在使用 Math.random() 时排除一系列值
- Javascript;使用math.random函数随机执行一个操作
- Math.random()如何在javascript中工作
- for loop, Math.random() 不按预期运行
- 在 jQuery 中的 Math.random() 之后找到 “li”
- Math.floor(Math.random()) +1 实际上做了什么
- 掷骰子脚本均匀分布吗?(使用 Math.random())
- 带有 php 变量的 Math.random javascript
- 你如何使 Math.random 数组中的每一个第 9 个元素都是同一个元素?[JavaScript]
- Java - ScriptEngineManager nashorn Math.random 不起作用
- 无法正确使用Math.random
- 增加Math.random中某个数字在一定范围内的机会
- 如何将 Math.random() 方法生成的当前值与以前的值进行比较
- Javascript单选按钮鼠标悬停在移动图像上,使用math.random
- Math.Random在函数中总是相同的结果
- 如何在 JavaScript 中使用 Math.random 进行测试
- 谷歌地图API使用Math.random获取随机位置 - JS
- (Math.random()*x)+y 返回大于 x+y 的数字