为什么我不能使用_.map创建一个随机数组(new Array(n),Math.random)?

时间:2014-03-29 23:30:56

标签: javascript arrays underscore.js

我想创建一个0到1之间的随机数组,所以我尝试了:

var randList = _.map(new Array(5), Math.random);

但是我没有得到我期望的随机元素列表,而是得到了:

console.log(JSON.stringify(randList));
"[null,null,null,null,null]"

为什么我得到一个null数组而不是随机数?

3 个答案:

答案 0 :(得分:5)

实际上,你获得了一个undefined的数组 - 传递给map的函数甚至没有被触发过一次。这是因为使用new Array(Number)构造函数创建的数组有点奇怪 - 即使它的长度设置正确,它实际上也没有01等属性:< / p>

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是这种情况下的方法。 )

答案 1 :(得分:2)

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

答案 2 :(得分:0)

只想在raina77ow的优秀答案中添加一些测试用例。

实际上,new Array(5)不会在Array对象中分配5个属性。

无论你使用下划线还是普通的javascript Array.prototype.map(当然是在体面的浏览器中)都没关系。

以下是node.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' ]