Подтвердить что ты не робот

Как вы легко создаете javascript с пустыми матрицами?

В 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?

4b9b3361

Ответ 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;
    }
}

Ответ 2

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 возвращает новую длину массива.

Ответ 3

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

Ответ 4

Если вы действительно похожи на однострочные, и в вашем проекте используется underscore.js (который это отличная библиотека), вы можете писать только для записи:

_.range(9).map(function(n) {
      return _.range(9).map(function(n) {
            return null;
      });
});

Но я бы пошел со стандартной версией для цикла, упомянутой выше.

Ответ 5

Это точное решение вашей проблемы, но я бы посоветовал не инициализировать матрицу значением по умолчанию, которое представляет собой "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] ]

Ответ 6

Вопрос немного неоднозначен, так как 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.:)

Ответ 7

Что-то о Array.fill Мне нужно упомянуть.

Если вы просто используете метод ниже для создания матрицы 3x3.

Array(3).fill(Array(3).fill(0));

Вы увидите, что значения в матрице являются ссылкой.

введите описание изображения здесь


Оптимизированное решение (предотвращение передачи по ссылке):

Если вы хотите передать значение, а не ссылку, вы можете использовать Array.map для его создания.

Array(3).fill(null).map(() => Array(3).fill(0));

введите описание изображения здесь

Ответ 8

Помогите спастись!

[1..9].map -> [1..9].map -> null

Ответ 9

Здесь один, без циклов:

(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))

Ответ 10

Мне нравится использовать строки для этого

Строки могут повторяться с повторением функции. Они могут быть отображены для изменения значений, которые затем могут быть необязательно отображены для установки значений по умолчанию. В этом случае я выбрал undefined.

Array.fill тоже хорош, но я хотел показать другую альтернативу.

var matrix = ".".repeat(8).split(".").map( s=> {return ".".repeat(8).split(".").map(s => {return undefined})});

console.log(matrix);

Ответ 11

Ну, вы можете создать пустой массив 1-D, используя явный конструктор Array:

a = new Array(9)

Чтобы создать массив массивов, я думаю, что вам нужно написать вложенный цикл, как описано в Marc.

Ответ 12

Вы можете добавить функциональность к массиву, расширив его объект 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); });

Ответ 13

Я тоже сделаю свой снимок

var c = Array;

for( var i = 0, a = c(9); i < 9; a[i] = c(9), i++ );

console.log( a.join(",") );
//",,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,"

Читаемость и поддержка!