Aqui está um artigo simples sobre algumas dicas sobre o uso de matrizes JavaScript. Usaremos métodos diferentes para combinar/mesclar duas matrizes JS, além de discutir as vantagens/desvantagens de cada método.
Vamos considerar a seguinte situação primeiro:
A cópia do código é a seguinte:
var a = [1, 2, 3, 4, 5, 6, 7, 8, 9];
var B = ["Foo", "Bar", "Baz", "Bam", "Bun", "Fun"];
Obviamente, o resultado da combinação mais simples deve ser:
A cópia do código é a seguinte:
[[
1, 2, 3, 4, 5, 6, 7, 8, 9,
"Foo", "Bar", "Baz", "Bam" "Bun", "Fun"
]
concat (..)
Esta é a prática mais comum:
A cópia do código é a seguinte:
var c = A.Concat (B);
um; // [1,2,3,4,5,6,7,8,9]
b; // ["Foo", "Bar", "Baz", "Bam", "Bun", "Fun"]
c; // [1,2,3,4,5,6,7,8,9, "Foo", "Bar", "Baz", "Bam", "Bun", "Fun"]
Como você pode ver, C é uma nova matriz que representa uma combinação de duas matrizes A e B e mantém invariantes A e B. Simples?
Mas se A tem 10.000 elementos e B tem 10.000 elementos? C terá 20.000 elementos, portanto, o uso da memória de A e B dobrará.
"Sem problemas!" você disse. Que eles sejam coletados de lixo, defina A e B como nula, o problema é resolvido!
a = b = nulo; // 'a' e 'b' são reciclados
hehe. Para pequenas matrizes com apenas alguns elementos, tudo bem. Mas, para grandes matrizes ou sistemas com memória limitada, esse processo precisa ser repetido com frequência, ele realmente tem muitas melhorias.
Inserção de loop
Ok, vamos copiar o conteúdo de uma matriz para outra, usando: Array#push (..)
A cópia do código é a seguinte:
// `b` para` a`
for (var i = 0; i <b.length; i ++) {
a.push (b [i]);
}
um; // [1,2,3,4,5,6,7,8,9, "Foo", "Bar", "Baz", "Bam", "Bun", "Fun"]
b = nulo;
Agora, a matriz A tem o conteúdo da matriz b.
Parece haver uma melhor pegada de memória.
Mas e se a matriz A for menor? Por razões de memória e velocidade, você pode querer colocar A menor na frente de B. Não tem problema, basta mudar o push (..) para dividir (..):
A cópia do código é a seguinte:
// `a` em` b`:
for (var i = A.Length-1; i> = 0; i--) {
B.UnShift (A [i]);
}
b; // [1,2,3,4,5,6,7,8,9, "Foo", "Bar", "Baz", "Bam", "Bun", "Fun"]
Habilidades funcionais
No entanto, o loop for realmente feio e difícil de manter. Podemos fazer melhor?
Esta é a nossa primeira tentativa, usando a matriz#Reduce:
A cópia do código é a seguinte:
// `b` em` a`:
a = B.Reduce (função (coll, item) {
Coll.push (item);
retornar coll;
}, a);
um; // [1,2,3,4,5,6,7,8,9, "Foo", "Bar", "Baz", "Bam", "Bun", "Fun"]
// ou `a` em` b`:
b = A.RedUteright (função (coll, item) {
Coll.unshift (item);
retornar coll;
}, b);
b; // [1,2,3,4,5,6,7,8,9, "Foo", "Bar", "Baz", "Bam", "Bun", "Fun"]
Matriz#Reduce (..) e a matriz#ReduceRight (..) são legais, mas são um pouco desajeitados. A função de seta de ES6 => reduzirá a quantidade de código, mas ainda requer uma função e cada elemento precisa ser chamado uma vez, o que não é perfeito.
Então, que tal isso:
A cópia do código é a seguinte:
// `b` em` a`:
A.Push.Apply (A, B);
um; // [1,2,3,4,5,6,7,8,9, "Foo", "Bar", "Baz", "Bam", "Bun", "Fun"]
// ou `a` em` b`:
B.UnShift.Apply (B, A);
b; // [1,2,3,4,5,6,7,8,9, "Foo", "Bar", "Baz", "Bam", "Bun", "Fun"]
Este é um lugar muito melhor? Especialmente porque o método Netift (..) não precisa se preocupar com a classificação reversa anterior aqui. A operação de fala do ES6 será mais bonita: a.push (... b) ou b.unshift (... a
Limite de comprimento máximo para matriz
O primeiro grande problema é que o uso da memória dobra (apenas temporário, é claro!), Basicamente, copia elementos na pilha por meio de chamadas de função. Além disso, diferentes motores JS têm limitações no comprimento dos dados de cópia.
Portanto, se a matriz tiver um milhão de elementos, você definitivamente estará além do limite que o empurrão (...) ou o desvio (...) permite a pilha de chamadas. Infelizmente, ele fará um ótimo trabalho ao lidar com milhares de elementos, mas você deve ter cuidado para não exceder o limite de comprimento razoável.
NOTA: Você pode tentar a emenda (...), que tem esse problema como push (...) e desativado (...).
Existe uma maneira de evitar esse limite máximo de comprimento.
A cópia do código é a seguinte:
Função CombineInto (a, b) {
var Len = A.Lengen;
for (var i = 0; i <len; i = i+5000) {
B.UnShift.Apply (B, A.Slice (I, I+5000));
}
}
Espere, nossa legibilidade voltou para trás. É isso, pode ficar cada vez pior, haha.