Neste tutorial, você aprenderá a trabalhar com arrays 2D em JavaScript. O JavaScript não possui suporte integrado para arrays 2D. Isso não é um grande problema porque arrays em JavaScript podem conter outros arrays como seus elementos. Isso significa que podemos criar arrays 2D em JavaScript criando um array de arrays.
Vamos revisar alguns dos fundamentos, como inicialização de matriz 2D e, em seguida, implementar funcionalidades adicionais, como obter e definir valores de elementos em uma matriz 2D.
Criando Arrays 2D em JavaScript
Arrays regulares em JavaScript são unidimensionais. Criamos arrays regulares usando a notação literal ou usando o Array
construtor como mostrado abaixo:
1 |
let numbers = [1, 2, 4, 59, 589, 126]; |
2 |
let names = new Array('Peter', 'Adam', 'Andy', 'Jake', 'Andrew'); |
3 |
|
4 |
console.log(numbers); |
5 |
// Outputs: [ 1, 2, 4, 59, 589, 126 ]
|
6 |
|
7 |
console.log(names); |
8 |
// Outputs: [ 'Peter', 'Adam', 'Andy', 'Jake', 'Andrew' ]
|
Podemos criar matrizes 2D de maneira semelhante. Aqui está um exemplo:
1 |
let matrix_a = [[1, 2, 4], [59, 589, 126], [34, 39, 27]]; |
2 |
let seating_arrangement = new Array(['Peter', 'Adam', 'Andy'], ['Jake', 'Andrew', 'Sam'], ['Jill', 'Jordan', 'Emma']); |
3 |
|
4 |
console.log(matrix_a); |
5 |
// Outputs: [ [ 1, 2, 4 ], [ 59, 589, 126 ], [ 34, 39, 27 ] ]
|
6 |
|
7 |
console.log(seating_arrangement); |
8 |
/* Outputs:
|
9 |
[
|
10 |
[ 'Peter', 'Adam', 'Andy' ],
|
11 |
[ 'Jake', 'Andrew', 'Sam' ],
|
12 |
[ 'Jill', 'Jordan', 'Emma' ]
|
13 |
]
|
14 |
*/
|
É importante lembrar que, ao contrário de linguagens como C++, os arrays 2D em JavaScript não possuem um número fixo de linhas e colunas. Portanto, se quisermos que nosso array seja um retângulo – ie. com todas as linhas e colunas do mesmo comprimento – temos que garantir que todos os subarrays tenham o mesmo comprimento.
Em nosso exemplo acima, criamos nosso matrix_a
array com três arrays. Isso fornece três linhas para nossa matriz 2D. Agora, cada uma dessas matrizes tinha três elementos próprios. Isso resultou em três colunas em nossa matriz 2D. Poderíamos ter limitado nossa terceira matriz a apenas dois elementos e matrix_a
ainda seria um array 2D. No entanto, seria uma matriz 2D irregular.
No restante deste tutorial, nosso foco será trabalhar com matrizes 2D que possuem um número fixo de linhas e colunas. Vamos definir uma função de inicialização de array com essas restrições em mente.
Inicializando Arrays 2D em JavaScript
Sabemos que uma matriz 2D consiste em uma matriz de matrizes que compõem suas linhas e colunas. Criar e inicializar um array 2D é simplesmente uma questão de usar o construtor do array repetidamente para preencher os elementos do nosso array principal. A seguinte função faz isso para nós:
1 |
function create_2d_array(rows, columns, value = 0) { |
2 |
let array_2d = new Array(rows); |
3 |
|
4 |
for(let i = 0; i < rows; i++) { |
5 |
array_2d[i] = new Array(columns).fill(value); |
6 |
}
|
7 |
|
8 |
return array_2d; |
9 |
}
|
10 |
|
11 |
matrix_a = create_2d_array(3, 4, 1); |
12 |
console.log(matrix_a); |
13 |
// Outputs: [ [ 1, 1, 1, 1 ], [ 1, 1, 1, 1 ], [ 1, 1, 1, 1 ] ]
|
14 |
|
15 |
matrix_b = create_2d_array(4, 3, "Pie"); |
16 |
console.log(matrix_b); |
17 |
/* Outputs:
|
18 |
[
|
19 |
[ 'Pie', 'Pie', 'Pie' ],
|
20 |
[ 'Pie', 'Pie', 'Pie' ],
|
21 |
[ 'Pie', 'Pie', 'Pie' ],
|
22 |
[ 'Pie', 'Pie', 'Pie' ]
|
23 |
]
|
24 |
*/
|
Nossa função aceita três argumentos, o primeiro é o número de linhas que indica quantos arrays o array pai deve conter. O segundo argumento é o número de colunas que determina quantos elementos devem existir em cada array. Por fim, temos o terceiro argumento que é o valor que queremos definir para cada elemento em nosso array 2D.
Dentro da função, criamos um for
loop que itera sobre todas as linhas e preenche o elemento pai da matriz com novas matrizes. Nós chamamos o fill()
método em cada um desses novos arrays para inicializá-los com nosso valor especificado. Todos os elementos são definidos como 0 se nenhum valor for fornecido pelo usuário.
Podemos tornar nossa função de inicialização de array mais curta usando o built-in map()
método. Aqui está o código para nossa função mais nova e mais curta:
1 |
function create_2d_array_with_map(rows, columns, value = 0) { |
2 |
let array_2d = new Array(rows).fill(0); |
3 |
return array_2d.map(() => new Array(columns).fill(value)); |
4 |
}
|
Como você pode ver acima, isso nos dará a mesma saída da função original. Desta vez, começamos como de costume com nosso array pai de elementos de linha. No entanto, chamamos o fill()
método para preenchê-lo com zeros. Depois disso, ligamos para o map()
método nesta matriz que retornou uma nova matriz com todos os elementos da matriz pai preenchida com matrizes de columns
número de elementos.
Alguns de vocês podem estar se perguntando se podemos tornar a função de inicialização de array ainda mais curta usando o fill()
método duas vezes em vez de mapear os valores conforme mostrado abaixo:
1 |
function create_2d_array_wrong(rows, columns, value) { |
2 |
return new Array(rows).fill(new Array(columns).fill(value)); |
3 |
}
|
Isso gerará um array com a mesma aparência dos anteriores, mas com um problema sutil. Porque o new Array(columns)
Se o construtor for chamado apenas uma vez, todos os arrays de colunas serão, na verdade, referências ao mesmo array.
Isso significa que você não poderá atualizar as colunas individuais de forma independente.
Obtendo e configurando valores de elemento em matrizes 2D
Você provavelmente já sabe que podemos acessar um elemento de array em qualquer índice usando o valor do índice e os índices são baseados em zero. Aqui está um exemplo:
1 |
let names = new Array('Peter', 'Adam', 'Andy', 'Jake', 'Andrew'); |
2 |
console.log(names[3]); |
3 |
// Outputs: Jake
|
Obtemos o quarto elemento em nosso array usando o valor de índice 3. Vamos tentar algo semelhante com nossos arrays 2D.
1 |
let matrix_a = [[1, 2, 4], [59, 589, 126], [34, 39, 27]]; |
2 |
let seating_arrangement = new Array(['Peter', 'Adam', 'Andy'], ['Jake', 'Andrew', 'Sam'], ['Jill', 'Jordan', 'Emma']); |
3 |
|
4 |
console.log(matrix_a[1]); |
5 |
// Outputs: [ 59, 589, 126 ]
|
6 |
|
7 |
console.log(matrix_a[1][1]); |
8 |
// Outputs: 589
|
9 |
|
10 |
console.log(seating_arrangement[0]); |
11 |
// Outputs: [ 'Peter', 'Adam', 'Andy' ]
|
12 |
|
13 |
console.log(seating_arrangement[0][2]); |
14 |
// Outputs: Andy
|
15 |
|
Como você pode ver, usar um único valor de índice nos dá um elemento da matriz pai e esse elemento é na verdade uma matriz em si. Temos que fornecer outro valor de índice para obter nosso elemento da matriz retornada.
Basicamente, o primeiro valor de índice nos dá o array dentro do qual devemos procurar o elemento. Chamaremos o primeiro valor de índice como row_index
. O segundo valor de índice nos dá o elemento que estamos procurando dentro de nosso array retornado array. Chamaremos o segundo valor de índice como col_index
. Podemos usar a seguinte instrução para acessar qualquer elemento que quisermos dentro de nosso array 2D.
1 |
my_2d_array[row_idx][col_idx] |
Isso ficará mais claro a partir do seguinte trecho de código:
1 |
let seating_arrangement = new Array(['Peter', 'Adam', 'Andy'], ['Jake', 'Andrew', 'Sam'], ['Jill', 'Jordan', 'Emma']); |
2 |
|
3 |
console.table(seating_arrangement); |
4 |
/* Outputs:
|
5 |
┌─────────┬─────────┬──────────┬────────┐
|
6 |
│ (index) │ 0 │ 1 │ 2 │
|
7 |
├─────────┼─────────┼──────────┼────────┤
|
8 |
│ 0 │ 'Peter' │ 'Adam' │ 'Andy' │
|
9 |
│ 1 │ 'Jake' │ 'Andrew' │ 'Sam' │
|
10 |
│ 2 │ 'Jill' │ 'Jordan' │ 'Emma' │
|
11 |
└─────────┴─────────┴──────────┴────────┘
|
12 |
*/
|
13 |
|
14 |
console.log(seating_arrangement[0][2]); |
15 |
// Outputs: Andy
|
16 |
|
17 |
|
18 |
console.log(seating_arrangement[2][0]); |
19 |
// Outputs: Jill
|
Usando
console.table()
para registrar nossas matrizes 2D torna-as mais fáceis de entender.
No primeiro caso, obtemos o elemento da primeira linha (índice 0) e da terceira coluna (índice 2). Isso nos deu o valor andy. Da mesma forma, obtivemos Jill observando a terceira linha e a primeira coluna.
Agora que você sabe como acessar valores de elemento em uma determinada linha ou índice, é fácil definir um valor para esse elemento usando atribuição simples. Aqui está um exemplo:
1 |
let seating_arrangement = new Array(['Peter', 'Adam', 'Andy'], ['Jake', 'Andrew', 'Sam'], ['Jill', 'Jordan', 'Emma']); |
2 |
|
3 |
console.table(seating_arrangement); |
4 |
/* Outputs:
|
5 |
┌─────────┬─────────┬──────────┬────────┐
|
6 |
│ (index) │ 0 │ 1 │ 2 │
|
7 |
├─────────┼─────────┼──────────┼────────┤
|
8 |
│ 0 │ 'Peter' │ 'Adam' │ 'Andy' │
|
9 |
│ 1 │ 'Jake' │ 'Andrew' │ 'Sam' │
|
10 |
│ 2 │ 'Jill' │ 'Jordan' │ 'Emma' │
|
11 |
└─────────┴─────────┴──────────┴────────┘
|
12 |
*/
|
13 |
|
14 |
seating_arrangement[0][2] = 'Olivia'; |
15 |
|
16 |
seating_arrangement[2][0] = 'Ava'; |
17 |
|
18 |
console.table(seating_arrangement); |
19 |
/* Outputs:
|
20 |
┌─────────┬─────────┬──────────┬──────────┐
|
21 |
│ (index) │ 0 │ 1 │ 2 │
|
22 |
├─────────┼─────────┼──────────┼──────────┤
|
23 |
│ 0 │ 'Peter' │ 'Adam' │ 'Olivia' │
|
24 |
│ 1 │ 'Jake' │ 'Andrew' │ 'Sam' │
|
25 |
│ 2 │ 'Ava' │ 'Jordan' │ 'Emma' │
|
26 |
└─────────┴─────────┴──────────┴──────────┘
|
27 |
*/
|
Você se lembra quando mencionei anteriormente que criar arrays 2D com duas chamadas sucessivas para o fill()
O método criará problemas devido a todos os elementos se referirem ao mesmo objeto? Você mesmo pode verificar isso com o seguinte trecho de código:
1 |
function create_2d_array_wrong(rows, columns, value) { |
2 |
return new Array(rows).fill(new Array(columns).fill(value)); |
3 |
}
|
4 |
|
5 |
matrix_a = create_2d_array_wrong(3, 4, 1); |
6 |
console.log(matrix_a); |
7 |
// Outputs: [ [ 1, 1, 1, 1 ], [ 1, 1, 1, 1 ], [ 1, 1, 1, 1 ] ]
|
8 |
|
9 |
matrix_a[0][1] = 4; |
10 |
|
11 |
console.log(matrix_a); |
12 |
// Outputs: [ [ 1, 4, 1, 1 ], [ 1, 4, 1, 1 ], [ 1, 4, 1, 1 ] ]
|
Apenas alteramos o valor do elemento na primeira linha e na segunda coluna. No entanto, o valor na segunda coluna foi atualizado para todas as linhas.
Definindo valores inteiros de linha ou coluna
Agora aprenderemos como substituir o valor de toda a linha ou coluna em uma matriz 2D.
Substituir valores de linha é fácil porque toda a linha é basicamente uma matriz individual. A única restrição que colocaremos nessa substituição é que o array de substituição precisa ter o mesmo número de elementos que nosso array original. Aqui está a nossa função que faz a substituição:
1 |
function replace_row(array_2d, row_array, row_idx) { |
2 |
let array_2d_columns = array_2d[0].length; |
3 |
if(row_array.length == array_2d_columns) { |
4 |
array_2d[row_idx] = row_array; |
5 |
}
|
6 |
}
|
7 |
|
8 |
let seating_arrangement = new Array(['Peter', 'Adam', 'Andy'], ['Jake', 'Andrew', 'Sam'], ['Jill', 'Jordan', 'Emma']); |
9 |
|
10 |
console.table(seating_arrangement); |
11 |
/* Outputs:
|
12 |
┌─────────┬─────────┬──────────┬────────┐
|
13 |
│ (index) │ 0 │ 1 │ 2 │
|
14 |
├─────────┼─────────┼──────────┼────────┤
|
15 |
│ 0 │ 'Peter' │ 'Adam' │ 'Andy' │
|
16 |
│ 1 │ 'Jake' │ 'Andrew' │ 'Sam' │
|
17 |
│ 2 │ 'Jill' │ 'Jordan' │ 'Emma' │
|
18 |
└─────────┴─────────┴──────────┴────────┘
|
19 |
*/
|
20 |
|
21 |
replace_row(seating_arrangement, ['Olivia', 'Ava', 'Sophia'], 1); |
22 |
|
23 |
console.table(seating_arrangement; |
24 |
/* Outputs:
|
25 |
┌─────────┬──────────┬──────────┬──────────┐
|
26 |
│ (index) │ 0 │ 1 │ 2 │
|
27 |
├─────────┼──────────┼──────────┼──────────┤
|
28 |
│ 0 │ 'Peter' │ 'Adam' │ 'Andy' │
|
29 |
│ 1 │ 'Olivia' │ 'Ava' │ 'Sophia' │
|
30 |
│ 2 │ 'Jill' │ 'Jordan' │ 'Emma' │
|
31 |
└─────────┴──────────┴──────────┴──────────┘
|
32 |
*/
|
A substituição dos valores das colunas exigirá que percorramos todas as linhas porque cada elemento em uma coluna vem de uma matriz diferente. Também incluiremos uma condição que verifica uma correspondência no número de linhas e no comprimento da matriz da coluna de substituição. Aqui está o código da nossa função:
1 |
function replace_column(array_2d, column_array, col_idx) { |
2 |
if(column_array.length == array_2d.length) { |
3 |
for(let i = 0; i < column_array.length; i++) { |
4 |
array_2d[i][col_idx] = column_array[i]; |
5 |
}
|
6 |
}
|
7 |
}
|
8 |
|
9 |
let seating_arrangement = new Array(['Peter', 'Adam', 'Andy'], ['Jake', 'Andrew', 'Sam'], ['Jill', 'Jordan', 'Emma']); |
10 |
console.table(seating_arrangement); |
11 |
/* Outputs:
|
12 |
┌─────────┬─────────┬──────────┬────────┐
|
13 |
│ (index) │ 0 │ 1 │ 2 │
|
14 |
├─────────┼─────────┼──────────┼────────┤
|
15 |
│ 0 │ 'Peter' │ 'Adam' │ 'Andy' │
|
16 |
│ 1 │ 'Jake' │ 'Andrew' │ 'Sam' │
|
17 |
│ 2 │ 'Jill' │ 'Jordan' │ 'Emma' │
|
18 |
└─────────┴─────────┴──────────┴────────┘
|
19 |
*/
|
20 |
|
21 |
replace_column(seating_arrangement, ['Olivia', 'Ava', 'Sophia'], 1); |
22 |
console.table(seating_arrangement); |
23 |
/* Outputs:
|
24 |
┌─────────┬─────────┬──────────┬────────┐
|
25 |
│ (index) │ 0 │ 1 │ 2 │
|
26 |
├─────────┼─────────┼──────────┼────────┤
|
27 |
│ 0 │ 'Peter' │ 'Olivia' │ 'Andy' │
|
28 |
│ 1 │ 'Jake' │ 'Ava' │ 'Sam' │
|
29 |
│ 2 │ 'Jill' │ 'Sophia' │ 'Emma' │
|
30 |
└─────────┴─────────┴──────────┴────────┘
|
31 |
*/
|
Pensamentos finais
Neste tutorial, abordamos os fundamentos dos arrays 2D em JavaScript. Não há suporte integrado para arrays 2D em JavaScript. No entanto, ainda podemos criá-los facilmente inicializando um array de arrays. Este tutorial nos mostrou diferentes maneiras de inicializar matrizes 2D. Também aprendemos como obter ou definir o valor de elementos individuais em nossa matriz 2D ou substituir toda a linha ou coluna de uma vez.
Você também pode usar os métodos de matriz integrados com essas matrizes 2D para implementar funcionalidades adicionais, como emendar ou fatiar a matriz 2D.