Это будет сделано:
var arr = [];
var rows = 4;
var cols = 10;
for(var i = 0; i < rows + cols - 1; i++){
for(var j = Math.min(rows, i + 1) - 1; j >= Math.max(0, i - cols + 1); j--){
arr.push((j * cols) + i - j);
}
}
скрипка: http://jsfiddle.net/BmXpy/
РЕДАКТИРОВАТЬ: Вот моя попытка объяснить, как я пришел к этому.ВАЖНО, используйте приведенную выше таблицу чисел для визуализации и, если необходимо, распечатайте ее и вытяните диагонали.
Сначала подумайте о том, что мы хотим, это в основном диагонали.В приведенном выше примере первая диагональ равна 0, затем 10, 1, затем 20, 11, 2, затем 30, 21, 12, 3 и т. Д. Теперь, если подумать, сколько таких диагоналей, то это rows + cols - 1
.Вот где мы получаем первый цикл:
for(var i = 0; i < rows + cols - 1; i++){
Теперь, на секунду игнорируем границы.В общем случае (весь центр) каждая из этих диагоналей имеет длину «рядов».И поскольку мы хотим идти снизу вверх, нам нужен обратный цикл.Это будет выглядеть так для внутреннего цикла:
for(var j = rows - 1; j >= 0; j--){
Теперь мы должны иметь дело с обеими границами (левой и правой).
Для левой границы, если мы посмотрим на число диагоналей, длина которых меньше «строк», мы увидим, что это rows - 1
.И для этих диагоналей мы увидим, что длина каждой составляет i + 1
.Следующий внутренний цикл будет обрабатывать общий случай и левую границу:
for(var j = Math.min(rows, i + 1) - 1; j >= 0; j--){
Вы увидите, что для диагонали 0 это будет выполняться один раз, для 1 - дважды и т. Д. И для общего случая(i >= rows
) он будет запускать «строки» раз.
Теперь правая граница.Если мы посмотрим, какие диагонали справа короче, чем «строки», мы увидим, что все диагонали больше, чем «cols» (в примере, где cols равен 10, 0 проиндексировано, то есть строка 10 и выше).Замена j >= 0
на j >= Math.max(0, i - cols + 1)
приведет к 0 для общего случая и левой границы, но сократится для правой границы.Мы получаем это:
for(var j = Math.min(rows, i + 1) - 1; j >= Math.max(0, i - cols + 1); j--){
И, наконец, фактический расчет числа в каждой локации.i
представляет диагональ, а j
представляет индекс числа на диагонали j = 0
- это верхнее число, если вы смотрите на опубликованную таблицу чисел.Для j = 0
(верхний ряд чисел) число просто i
, для каждой строки ниже вершины нам нужно умножить число на «столбцы», чтобы получить число непосредственно под номером первой строки, затемномер нужно отрегулировать влево.Это делается путем вычитания j
, который является номером строки.Поэтому для j = 1
(2-й ряд) нам нужно переместить число влево на единицу (вычесть 1).Таким образом, у нас есть i
для горизонтального положения в первом ряду, + (j * cols)
, чтобы переместить его вниз к соответствующему ряду, а затем -j, чтобы отрегулировать его по диагонали (если вы нарисовали диагонали, отследите это для одного из нихчтобы получить хороший визуальный).Мы получаем это:
(j * cols) + i - j
Соберите все вместе, и вы получите мой окончательный код выше.Надеюсь, это имело смысл.