Ответ 1
var matrix = [];
for(var i=0; i<9; i++) {
matrix[i] = new Array(9);
}
... или:
var matrix = [];
for(var i=0; i<9; i++) {
matrix[i] = [];
for(var j=0; j<9; j++) {
matrix[i][j] = undefined;
}
}
В python вы можете сделать это:
[([None] * 9) for x in range(9)]
и вы получите следующее:
[[None, None, None, None, None, None, None, None, None],
[None, None, None, None, None, None, None, None, None],
[None, None, None, None, None, None, None, None, None],
[None, None, None, None, None, None, None, None, None],
[None, None, None, None, None, None, None, None, None],
[None, None, None, None, None, None, None, None, None],
[None, None, None, None, None, None, None, None, None],
[None, None, None, None, None, None, None, None, None],
[None, None, None, None, None, None, None, None, None]]
Как я могу сделать эквивалент в javascript?
var matrix = [];
for(var i=0; i<9; i++) {
matrix[i] = new Array(9);
}
... или:
var matrix = [];
for(var i=0; i<9; i++) {
matrix[i] = [];
for(var j=0; j<9; j++) {
matrix[i][j] = undefined;
}
}
Array.fill
Рассмотрим использование fill
:
Array(9).fill().map(()=>Array(9).fill())
Идея здесь состоит в том, что fill()
будет заполнять элементы с помощью undefined
, что достаточно, чтобы заставить map
работать с ними.
Вы также можете заполнить напрямую:
Array(9).fill(Array(9))
Альтернативы Array(9).fill()
включают
Array(...Array(9))
[].push(...Array(9))
[].concat(Array(9))
Array.from(Array(9))
Мы можем переписать решение немного более семантически, поскольку:
function array9() { return Array(9).fill(); }
array9().map(array9)
или
function array(n) { return Array(n).fill(); }
array(9).map(() => array(9))
Array.from
предоставляет нам необязательный второй аргумент отображения, поэтому у нас есть альтернатива написанию
Array.from(Array(9), () => Array.from(Array(9));
или, если вы предпочитаете
function array9(map) { return Array.from(Array(9), map); }
array9(array9);
Подробное описание и примеры см. в Документах Mozilla по Array.prototype.fill()
здесь.
и для Array.from()
, здесь.
Обратите внимание, что ни один из Array.prototype.fill()
и Array.from()
не имеет поддержки в Internet Explorer. A polyfill для IE доступен на вышеуказанных ссылках MDN.
partition(Array(81), 9)
если у вас есть утилита partition
. Здесь быстрый рекурсивный:
function partition(a, n) {
return a.length ? [a.splice(0, n)].concat(partition(a, n)) : [];
}
Мы можем выполнить более эффективную петлю с помощью
var a = [], b;
while (a.push(b = []) < 9) while (b.push(null) < 9);
Воспользовавшись тем, что push
возвращает новую длину массива.
var M1 = Array.from({length:9}, ()=>Array(9).fill(null))
// or Array.from({length:9}, ()=>Array.from({length:9}, ()=>null))
// initializing depending on i,j:
var M = Array.from({length:9},(_,i)=>Array.from({length:9}, (_,j)=>i+'x'+j))
// or Array.from(Array(9),(_,i)=>Array.from(Array(9), (_,j)=>i+'x'+j))
// Print it:
// console.table(M)
// M.forEach(r=>console.log(r))
document.body.innerHTML = `<pre>${M.map(r=>r.join('\t')).join('\n')}</pre>`
// JSON.stringify(M, null, 2) // bad for matrices
Если вы действительно похожи на однострочные, и в вашем проекте используется underscore.js (который это отличная библиотека), вы можете писать только для записи:
_.range(9).map(function(n) {
return _.range(9).map(function(n) {
return null;
});
});
Но я бы пошел со стандартной версией для цикла, упомянутой выше.
Это точное решение вашей проблемы, но я бы посоветовал не инициализировать матрицу значением по умолчанию, которое представляет собой "0" или "undefined", поскольку массивы в javascript являются просто обычными объектами, поэтому вы теряете трату усилия. Если вы хотите по умолчанию использовать ячейки для значимого значения, то этот фрагмент будет работать хорошо, но если вы хотите неинициализированную матрицу, не используйте эту версию:
/**
* Generates a matrix (ie: 2-D Array) with:
* 'm' columns,
* 'n' rows,
* every cell defaulting to 'd';
*/
function Matrix(m, n, d){
var mat = Array.apply(null, new Array(m)).map(
Array.prototype.valueOf,
Array.apply(null, new Array(n)).map(
function() {
return d;
}
)
);
return mat;
}
Использование:
< Matrix(3,2,'dobon');
> Array [ Array['dobon', 'dobon'], Array['dobon', 'dobon'], Array['dobon', 'dobon'] ]
Если вы хотите просто создать неинициализированный 2-D-массив, это будет более эффективным, чем ненужная инициализация каждой записи:
/**
* Generates a matrix (ie: 2-D Array) with:
* 'm' columns,
* 'n' rows,
* every cell remains 'undefined';
*/
function Matrix(m, n){
var mat = Array.apply(null, new Array(m)).map(
Array.prototype.valueOf,
new Array(n)
);
return mat;
}
Использование:
< Matrix(3,2);
> Array [ Array[2], Array[2], Array[2] ]
Вопрос немного неоднозначен, так как None
может перевести в undefined
или null
. null
- лучший выбор:
var a = [], b;
var i, j;
for (i = 0; i < 9; i++) {
for (j = 0, b = []; j < 9; j++) {
b.push(null);
}
a.push(b);
}
Если undefined
, вы можете быть неаккуратным и просто не беспокоить, все равно undefined
.:)
Что-то о Array.fill
Мне нужно упомянуть.
Если вы просто используете метод ниже для создания матрицы 3x3.
Array(3).fill(Array(3).fill(0));
Вы увидите, что значения в матрице являются ссылкой.
Если вы хотите передать значение, а не ссылку, вы можете использовать Array.map
для его создания.
Array(3).fill(null).map(() => Array(3).fill(0));
Помогите спастись!
[1..9].map -> [1..9].map -> null
Здесь один, без циклов:
(Math.pow(10, 20)+'').replace((/0/g),'1').split('').map(parseFloat);
Заполните '20' для длины, используйте (необязательное) regexp для удобных преобразований и карт, чтобы обеспечить тип данных. Я добавил функцию в прототип Array, чтобы легко потянуть параметры "карты" в ваши функции. Немного рискованно, некоторые люди сильно выступают против трогательных родных прототипов, но это пригодится..
Array.prototype.$args = function(idx) {
idx || (idx = 0);
return function() {
return arguments.length > idx ? arguments[idx] : null;
};
};
// Keys
(Math.pow(10, 20)+'').replace((/0/g),'1').split('').map(this.$args(1));
[0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20]
// Matrix
(Math.pow(10, 9)+'').replace((/0/g),'1').split('').map(this.$args(1)).map(this.$args(2))
Мне нравится использовать строки для этого
Строки могут повторяться с повторением функции. Они могут быть отображены для изменения значений, которые затем могут быть необязательно отображены для установки значений по умолчанию. В этом случае я выбрал undefined.
Array.fill тоже хорош, но я хотел показать другую альтернативу.
var matrix = ".".repeat(8).split(".").map( s=> {return ".".repeat(8).split(".").map(s => {return undefined})});
console.log(matrix);
Ну, вы можете создать пустой массив 1-D, используя явный конструктор Array:
a = new Array(9)
Чтобы создать массив массивов, я думаю, что вам нужно написать вложенный цикл, как описано в Marc.
Вы можете добавить функциональность к массиву, расширив его объект prototype
.
Array.prototype.nullify = function( n ) {
n = n >>> 0;
for( var i = 0; i < n; ++i ) {
this[ i ] = null;
}
return this;
};
Тогда:
var arr = [].nullify(9);
или
var arr = [].nullify(9).map(function() { return [].nullify(9); });
Я тоже сделаю свой снимок
var c = Array;
for( var i = 0, a = c(9); i < 9; a[i] = c(9), i++ );
console.log( a.join(",") );
//",,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,"
Читаемость и поддержка!