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

javascript

67571 просмотра

15 ответа

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

Автор: priestc Источник Размещён: 17.05.2019 02:53

Ответы (15)


48 плюса

Решение
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;
    }
}
Автор: Richard JP Le Guen Размещён: 28.11.2011 07:48

51 плюса

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(), здесь .

Обратите внимание, что ни Internet Explorer, Array.prototype.fill()ни Array.from()поддержка не имеют. 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возвращает новую длину массива.

Автор: user663031 Размещён: 12.10.2015 11:19

10 плюса

// initializing depending on i,j:
var M=Array.from({length:9}, (_,i) => Array.from({length: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

Остерегайтесь, что делать это ниже, неправильно:

// var M=Array(9).fill([]) // since arrays are sparse
// or Array(9).fill(Array(9).fill(0))// initialization

// M[4][4] = 1
// M[3][4] is now 1 too!

Поскольку он создает одну и ту же ссылку на Array 9 раз, поэтому изменение элемента также изменяет элементы с тем же индексом других строк (поскольку это та же ссылка), поэтому для копирования необходим дополнительный вызов .slice или .map в строках. их (см. ответ torazaburo, который потерпел неудачу в этой ловушке)

примечание: это может выглядеть так в будущем, с предложением буквенного обозначения среза (этап 1)

const M = [...1:10].map(i => [...1:10].map(j => i+'x'+j))
Автор: caub Размещён: 10.10.2015 07:44

4 плюса

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

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

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

Автор: kubetz Размещён: 28.11.2011 08:00

3 плюса

Это точное решение вашей проблемы, но я бы посоветовал не инициализировать матрицу значением по умолчанию, которое представляет «0» или «неопределенный», поскольку массивы в 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-мерный массив, это будет более эффективным, чем ненужная инициализация каждой записи :

/**
* 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] ]
Автор: dobon Размещён: 12.08.2014 09:26

2 плюса

Есть кое-что о чем Array.fillя должен упомянуть.

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

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

Вы обнаружите, что значения в матрице являются справочными.

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


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

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

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

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

Автор: HectorGuo Размещён: 23.01.2017 08:50

1 плюс

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

Автор: Amadan Размещён: 28.11.2011 07:53

0 плюса

Coffeescript на помощь!

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

Автор: david Размещён: 28.11.2011 08:01

0 плюса

Вот один, без зацикливания:

(Math.pow(10, 20)+'').replace((/0/g),'1').split('').map(parseFloat);

Заполните '20' для длины, используйте (опционально) регулярное выражение для удобных преобразований и карту, чтобы обеспечить тип данных. Я добавил функцию в прототип 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))
Автор: Erik Schoel Размещён: 16.06.2015 11:45

0 плюса

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

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

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

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

console.log(matrix);

Автор: Tschallacka Размещён: 31.08.2017 12:09

0 плюса

лучше. это точно будет работать.

let mx = Matrix(9, 9);

function Matrix(w, h){
    let mx = Array(w);
    for(let i of mx.keys())
        mx[i] = Array(h);
    return mx;
}


что было показано

Array(9).fill(Array(9)); // Not correctly working

Это не работает, потому что все ячейки заполнены одним массивом

Автор: Данила Летуновский Размещён: 22.06.2018 12:29

0 плюса

function createMatrix(row, column, isEmpty) {
        let tmpMatrix = []
        let tmpArray = []
        let rowColumn = row * column
        for (let i = 1; i <= rowColumn; i++) {
            isEmpty ?  tmpArray.push('none') :  tmpArray.push(i)

            if (i % column === 0) {
                tmpMatrix.push(tmpArray)
                tmpArray = []
            }
        }
        return tmpMatrix
    }

createMatrix(5, 3, true)
Автор: Driton Haxhiu Размещён: 02.03.2019 12:28

-1 плюса

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

a = new Array(9)

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

Автор: Bob Gilmore Размещён: 28.11.2011 07:51

-1 плюса

Вы можете добавить функциональность в массив, расширяя его 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); });
Автор: RightSaidFred Размещён: 28.11.2011 07:52

-1 плюса

Я тоже сделаю это

var c = Array;

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

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

Читаемый и ремонтопригодный!

Автор: Esailija Размещён: 28.11.2011 08:06
Вопросы из категории :
32x32