簡體   English   中英

為什么我不能使用_.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]"

為什么我得到一個null數組而不是隨機數?

實際上,你得到一個undefined的數組 - 並且傳遞給map函數甚至不會被觸發一次。 這是因為與創建數組new Array(Number)的構造有點怪-即使它的長度設置正確,但實際上並沒有01個特性:

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的優秀答案中添加一些測試用例。

實際上,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' ]

map結果返回一個長度為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' ]

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM