2013-11-02 3 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]]); 

Зачем это для цикла установить все индексы до 30 000? Я неправильно использую JavaScript-массивы?

Спасибо.

+0

Что вы хотите от этого сделать? – Popnoodles

+0

Как вы ожидаете быть вашим выходным массивом? –

+0

Я ожидаю, что массив будет увеличиваться на единицу в случайных точках между 1 и 6. Например, если dieOne = 5 и dieTwo = 3, я ожидал бы, что кости [5] [3] будут увеличиваться на единицу. –

ответ

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" 

То, что вы, вероятно, хотите делать

Похоже, что вы на самом деле хотите массив от 6Массивы каждый o f 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] 
]; 

Тогда для вашего цикла, чтобы быть

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 я не могу создать сетку 6x6 с двухмерным массивом, я должен сделать 6 массивов, каждый из которых заполнен 6 значениями. Я правильно понимаю это? –

1

Это, в то время как (к сожалению) технически действует JavaScript, не собирается делать то, что вы хотите:

dice[[dieOne][dieTwo]] 

Выражение foo[bar] является ссылкой на foo «s свойство с именем bar. Ключи свойств всегда строки или числовые (технически только строки, но если мы говорим о массивах, имеет смысл думать о клавишах как о числах). Таким образом, когда JavaScript видит выражение dice[[dieOne][dieTwo]], он пытается принудить [dieOne][dieTwo] в действительный ключ свойства. Wackiness вытекает следующим образом:

  • [dieOne] оценивает на массив, содержащий один элемент с индексом 0, значение которого dieOne; пусть этот промежуточный результат будет далее обозначаться как foo.
  • foo[dieTwo] оценивает в отношении имущества foo, индекс которого dieTwo
  • Поскольку в каждой итерации вашего цикла, dieTwo всегда> 0, и foo массив только чей действительный индекс 0, dieTwo вне границ. К сожалению, массив возвращает undefined вместо того, чтобы выбросить ошибку.
  • Значение undefined принуждено к строке, поэтому его можно использовать как ключ свойства. Технически, только строки являются ключами свойств; в соответствии со стандартом, массивы являются поддельными. Значение "undefined".
  • Поскольку ваш код не присвоил значение dice["undefined"], с первой попытки ++ он видит свое начальное значение как, опять же, undefined. И снова, вместо того, чтобы бросать исключение, он, к сожалению, принуждает undefined к тому, что он похож на вас, номер 0, увеличивается до 1 и присваивает его новому dice["undefined"].
    • Если ваш браузер придерживался стандарта ES5, undefined++ будет NaN.
  • Так как следующие шаги, описанные выше, [dieOne][dieTwo] ВСЕГДА принуждают "undefined", говорит свойство dice увеличивается один раз на каждой итерации цикла, придавая ему окончательное значение 30000.
    • Если ваш браузер придерживается стандарта ES5, NaN++ будет NaN, независимо от того, сколько раз вы его увеличиваете.
  • Так как любой [foo][bar], где bar не 0, когда принуждают к ключу собственности, будет "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 Increment Operator_ и 9.4 для _ToNumber_. –

+0

@PaulS Абсолютно верно; Я говорю ES5, потому что это то, что у меня было передо мной = D Спасибо за разъяснение – sqykly

Смежные вопросы