2013-11-02 50 views
1

我目前正在研究一些非常基本的東西,但我很難。我想在二維數組中獲得一個隨機索引,並在每次for循環翻轉時將其增加一。在JavaScript中增加多維數組

var dice = [[],[]]; 

// Get totals. 
for(var i = 0; i < 30000; i++) { 
    var dieOne = Math.floor(Math.random() * 6 + 1); 
    var dieTwo = Math.floor(Math.random() * 6 + 1); 
     dice[[dieOne][dieTwo]]++; 
    } 

    // All index values equal 30,000 for some reason 
    alert(dice[[1][3]]); 

爲什麼這個for循環將所有索引設置爲30,000?我錯誤地使用JavaScript數組?

謝謝。

+0

你想幹什麼? – Popnoodles

+0

你如何期望成爲你的輸出數組? –

+0

我期待陣列在1和6之間隨機點增加一個。 例如,如果dieOne = 5且dieTwo = 3,我希望dice [5] [3]增加1。 –

回答

2

你在做什麼

好像你誤會的你在做什麼的語法。這是目前相當於

var dieOne = Math.floor(Math.random() * 6 + 1); 
var dieTwo = Math.floor(Math.random() * 6 + 1); 
var foo; 
foo = dieOne; // a number 
foo = [foo]; // an array with one number in it 
foo = foo[dieTwo]; // probably undefined, unlikely case of `dieTwo = 0` 
        // which would give back `dieOne` 
dice[foo] = dice[foo] + 1; // most likely trying to add 1 to property `undefined` 

再後來你做

foo = [1]; // an array length 1 
foo = foo[3]; // undefined, it doesn't have an item here 
foo = dice[foo]; // = dice[undefined] = undefined 
alert(foo); // alerting "undefined" 

你可能想要做什麼

看起來你需要的是一個陣列 of 6陣列每個o f 6Numbers;構建自己喜歡的方式

var dice = [ 
    [0, 0, 0, 0, 0, 0], 
    [0, 0, 0, 0, 0, 0], 
    [0, 0, 0, 0, 0, 0], 
    [0, 0, 0, 0, 0, 0], 
    [0, 0, 0, 0, 0, 0], 
    [0, 0, 0, 0, 0, 0] 
]; 

那麼對於你的循環是

var dieOne, dieTwo, i; 
for(i = 0; i < 30000; ++i) { 
    dieOne = Math.floor(Math.random() * 6); // indices start at 0 and 
    dieTwo = Math.floor(Math.random() * 6); // 6 of them means max is 5 
    dice[dieOne][dieTwo]++; // count the brackets here.. 
} 

然後說你想知道有多少次你不得不dieOne = 1,dieTwo = 3,你會看

dice[1][3]; // count the brackets again. 
+0

我試過把所有的索引都設置爲零,如骰子[[i] [j]] = 0;它仍然不起作用。也許我誤解你的意思是「未定義?」 –

+0

請在我描述'foo'發生了什麼的地方再讀一遍。我使用'foo'將代碼行分解爲解釋器試圖用代碼執行的步驟。 –

+0

嗯..所以在JavaScript中我不能創建一個2維數組的6x6網格,我必須創建一個6數組,每個數組都填充6個值。我是否正確理解這一點? –

1

這一點,而(不幸)在技術上有效的JavaScript,不會做你想要的:

dice[[dieOne][dieTwo]] 

表達式foo[bar]是對foo的屬性bar的引用。屬性鍵總是字符串或數字(技術上只是字符串,但如果我們談論數組,則將鍵看作數字更有意義)。因此,當JavaScript看到表達式dice[[dieOne][dieTwo]]時,它會嘗試將[dieOne][dieTwo]強制轉換爲有效的屬性鍵。隨之而來的古怪如下:

  • [dieOne]的計算結果爲包含一個元素在索引0處,其值是dieOne陣列;讓這個中間結果在下文中被稱爲foo
  • foo[dieTwo]評估爲到其索引爲dieTwo
  • 由於,在循環的每一次迭代,dieTwo是總是> 0的foo屬性的引用,並且foo是一個數組,其僅有效的索引是0dieTwo是出的界限。不幸的是,該數組返回undefined而不是拋出錯誤。
  • undefined被強制爲一個字符串,因此它可以用作屬性鍵。從技術上講,只有字符串是屬性鍵;根據標準,陣列是僞造的。值爲"undefined"
  • 由於您的代碼尚未將值賦予dice["undefined"],所以第一次嘗試++時,它將其初始值再次視爲undefined。再次,不是拋出異常,它不幸地將undefined強制轉換爲看起來像你想要的,數字0,增量爲1,並將其分配給新定義的dice["undefined"]
    • 如果您的瀏覽器遵循ES5標準,undefined++將是NaN
  • 由於按照上述步驟,[dieOne][dieTwo]是ALWAYS強制爲"undefined",所述dice屬性是基於循環的每次迭代遞增一次,給它的一個30000最終值。
    • 如果您的瀏覽器遵循ES5標準,則無論您增加多少次,NaN++都應爲NaN
  • 因爲任何[foo][bar]其中bar0,當強制轉換爲屬性鍵,將"undefined"根據上述步驟,dice[[n][m]]總是相當於dice["undefined"]。只是爲了好玩,試試dice[[n][0]]其中n是除"undefined"以外的任何東西,以驗證它不是30000,因此我是對的,並且應該有複選標記= D。

所以這就是爲什麼你會得到這樣的結果。

在JS中沒有真正的多維數組,如果您將它想象爲一個數組數組,可能會更少地混淆語法。然後,你可以把它分解爲若干步驟:

  • dice是一個數字數組的數組,
  • 所以dice[n]是數字數組,
  • 所以dice[n][m]是我想要的號碼。

因此,這裏是你的大致正確的程序將是什麼樣子:

/* We don't like undefined anymore, so make an array of 7 arrays of 7 zeroes */ 
/* (we need 7 because JS array indexes start at 0 and you're using values 1-6) */ 
var dice = [ 
    [0,0,0,0,0,0,0], 
    [0,0,0,0,0,0,0], 
    [0,0,0,0,0,0,0], 
    [0,0,0,0,0,0,0], 
    [0,0,0,0,0,0,0], 
    [0,0,0,0,0,0,0], 
    [0,0,0,0,0,0,0] 
]; 
/* Now I'm tired of repeating myself, so let's DRY things up */ 
function roll() { 
    return Math.floor(Math.random()*6) + 1; 
} 
var dieOne, dieTwo; 
for (var i = 0 ; i < 30000 ; i++) { 
    dieOne = roll(); 
    dieTwo = roll(); 
    dice[dieOne][dieTwo]++; 
} 

看是最後一行的最重要的部分。

  • dice是數字的陣列的陣列,
  • 所以dice[dieOne]是數字數組,
  • 所以dice[dieOne][dieTwo]是一個數字,我們可以有意義地遞增。
+0

我認爲這個答案更清楚地解釋了原始代碼中發生的事情,比我的'+ 1'更清楚,但是你怎麼看待下面的_ES5_ - 它不是它的第一個標準;此行爲也在_ES3_,[** spec **](http://www.ecma-international.org/publications/files/ECMA-ST-ARCH/ECMA-262,%203rd%20edition,%20December%201999 .PDF);部分11.3.1爲_Postfix遞增運算符_和9.4爲_ToNumber_。 –

+0

@PaulS絕對正確;我說ES5是因爲這就是我在我面前= D感謝您的澄清 – sqykly