Eu tenho uma matriz JavaScript dataArray
que eu quero enviar para uma nova matriz newArray
. Exceto que eu não quero newArray[0]
ser dataArray
. Quero inserir todos os itens na nova matriz:
var newArray = [];
newArray.pushValues(dataArray1);
newArray.pushValues(dataArray2);
// ...
ou melhor ainda:
var newArray = new Array (
dataArray1.values(),
dataArray2.values(),
// ... where values() (or something equivalent) would push the individual values into the array, rather than the array itself
);
Portanto, agora a nova matriz contém todos os valores das matrizes de dados individuais. Existe alguma abreviação pushValues
disponível para que eu não precise repetir cada indivíduo dataArray
, adicionando os itens um por um?
javascript
arrays
bba
fonte
fonte
Respostas:
Use a função concat , da seguinte maneira:
O valor de
newArray
será[1, 2, 3, 4]
(arrayA
earrayB
permanecerá inalterado;concat
cria e retorna uma nova matriz para o resultado).fonte
Google Chrome
: rápido (concat = vencedor)Opera
,: rápido (concat = vencedor) ,:IE
mais lento (concat = vencedor)Firefox
,: lento (push.apply = vencedor, mas 10 vezes mais lento que o concat do Chrome) ... fale de má implementação do mecanismo JS .push
não achatará uma matriz de valores.concat
alcança o que a pergunta exige.Desde que suas matrizes não sejam enormes (veja a advertência abaixo), você pode usar o
push()
método da matriz à qual deseja acrescentar valores.push()
pode usar vários parâmetros para que você possa usar seuapply()
método para transmitir a matriz de valores a serem enviados como uma lista de parâmetros de função. Isso tem a vantagemconcat()
de adicionar elementos à matriz no lugar, em vez de criar uma nova matriz.No entanto, parece que para matrizes grandes (da ordem de 100.000 membros ou mais), esse truque pode falhar . Para essas matrizes, usar um loop é uma abordagem melhor. Consulte https://stackoverflow.com/a/17368101/96100 para obter detalhes.
Você pode generalizar isso em uma função:
... ou adicione-o ao
Array
protótipo:... ou emule o
push()
método original permitindo vários parâmetros usando o fato de queconcat()
, comopush()
, permite vários parâmetros:Aqui está uma versão baseada em loop do último exemplo, adequada para matrizes grandes e todos os principais navegadores, incluindo o IE <= 8:
fonte
newArray.push.apply(newArray, dataArray1);
dá o mesmo queArray.prototype.push.applay(newArray,dataArra1);
Array.prototype.concat
não é ruim, é simplesmente mal compreendido e às vezes mal utilizado. Nessas circunstâncias, é apenas mal compreendido, mas não mal utilizado.Vou adicionar mais uma resposta "à prova de futuro"
No ECMAScript 6, você pode usar a sintaxe de propagação :
A sintaxe de propagação ainda não está incluída nos principais navegadores. Para a compatibilidade atual, consulte esta tabela de compatibilidade (atualizada continuamente) .
No entanto, você pode usar a sintaxe de propagação com o Babel.js .
editar:
Veja a resposta de Jack Giffin abaixo para mais comentários sobre desempenho. Parece que concat ainda é melhor e mais rápido que o operador spread.
fonte
newArray.apply(newArray, dataArray1)
.Encontrou uma maneira elegante da MDN
Ou você pode usar o
spread operator
recurso do ES6:fonte
Isso resolve o seu problema?
fonte
O seguinte me parece mais simples:
Como "push" recebe um número variável de argumentos, você pode usar o
apply
método dapush
função para enviar todos os elementos de outra matriz. Ele constrói uma chamada para envio usando seu primeiro argumento ("newArray" aqui) como "this" e os elementos da matriz como os argumentos restantes.A
slice
primeira instrução obtém uma cópia da primeira matriz, para que você não a modifique.Atualizar Se você estiver usando uma versão do javascript com a fatia disponível, poderá simplificar a
push
expressão para:fonte
A função abaixo não apresenta problemas com o comprimento das matrizes e apresenta um desempenho melhor do que todas as soluções sugeridas:
infelizmente, o jspref se recusa a aceitar meus envios, então aqui estão os resultados usando o benchmark.js
Onde
para loop e push é:
Pressione Aplicar:
operador de spread:
e finalmente o 'comprimento definido e loop for' é a função acima
fonte
𝗥𝗲𝘀𝗲𝗮𝗿𝗰𝗵 𝗔𝗻𝗱 𝗥𝗲𝘀𝘂𝗹𝘁𝘀
Pelos fatos, um teste de desempenho no jsperf e a verificação de algumas coisas no console são realizados. Para a pesquisa, é utilizado o site irt.org . Abaixo está uma coleção de todas essas fontes reunidas, além de uma função de exemplo na parte inferior.
Como visto acima, eu argumentaria que o Concat é quase sempre o caminho a seguir tanto para o desempenho quanto para a capacidade de manter a escassez de matrizes sobressalentes. Em seguida, para curtidas de matriz (como DOMNodeLists como
document.body.children
), eu recomendaria usar o loop for porque é o segundo melhor desempenho e o único outro método que retém matrizes esparsas. Abaixo, abordaremos rapidamente o que se entende por matrizes esparsas e curtidas de matrizes para esclarecer a confusão.𝗧𝗵𝗲 𝗙𝘂𝘁𝘂𝗿𝗲
No começo, algumas pessoas podem pensar que isso é um acaso e que os fornecedores de navegadores acabarão otimizando o Array.prototype.push para serem rápidos o suficiente para vencer o Array.prototype.concat. ERRADO! Array.prototype.concat sempre será mais rápido (pelo menos em princípio), porque é uma cópia-e-colar simples sobre os dados. Abaixo está um diagrama persuado-visual simplificado de como pode ser uma implementação de matriz de 32 bits (observe que implementações reais são MUITO mais complicadas)
Como visto acima, tudo o que você precisa fazer para copiar algo assim é quase tão simples quanto copiá-lo byte por byte. Com Array.prototype.push.apply, é muito mais do que uma simples copiar e colar sobre os dados. O ".apply" deve verificar cada índice na matriz e convertê-lo em um conjunto de argumentos antes de passá-lo para Array.prototype.push. Em seguida, o Array.prototype.push precisa alocar adicionalmente mais memória a cada vez e (para algumas implementações de navegador) talvez até recalcular alguns dados de pesquisa de posição quanto à escassez.
Uma maneira alternativa de pensar nisso é essa. A matriz de origem 1 é uma grande pilha de papéis grampeados. A matriz de origem dois também é outra grande pilha de papéis. Seria mais rápido para você
Na analogia acima, a opção 1 representa Array.prototype.concat, enquanto a 2 representa Array.prototype.push.apply. Vamos testar isso com um JSperf semelhante, diferindo apenas no fato de este testar os métodos em matrizes esparsas, e não sólidas. Pode-se encontrar aqui .
Portanto, descubro que o futuro do desempenho desse caso de uso específico não está em Array.prototype.push, mas em Array.prototype.concat.
𝗖𝗹𝗮𝗿𝗶𝗳𝗶𝗰𝗮𝘁𝗶𝗼𝗻𝘀
𝗦𝗽𝗮𝗿𝗲 𝗔𝗿𝗿𝗮𝘆𝘀
Quando certos membros da matriz estão simplesmente ausentes. Por exemplo:
Como alternativa, o javascript permite inicializar matrizes sobressalentes facilmente.
𝗔𝗿𝗿𝗮𝘆-𝗟𝗶𝗸𝗲𝘀
Um tipo de matriz é um objeto que possui pelo menos uma
length
propriedade, mas não foi inicializado comnew Array
ou[]
; Por exemplo, os objetos abaixo são classificados como de matriz.Observe o que acontece usando um método que coage gostos de matrizes em matrizes como fatia.
Mostrar snippet de código
Observe o que acontece usando um método que não coage gostos de matrizes em matrizes como concat.
Mostrar snippet de código
fonte
Com o JavaScript ES6, você pode usar o operador ... como um operador de propagação que essencialmente converterá a matriz em valores. Então, você pode fazer algo assim:
Embora a sintaxe seja concisa, não sei como isso funciona internamente e quais são as implicações de desempenho em grandes matrizes.
fonte
Array.push.apply
técnica.Aqui está a maneira ES6
fonte
Há várias respostas falando sobre Array.prototype.push.apply . Aqui está um exemplo claro:
Se você possui a sintaxe do ES6:
fonte
Se você deseja modificar a matriz original, pode espalhar e pressionar:
Se você deseja garantir que apenas itens do mesmo tipo entrem na
source
matriz (sem misturar números e seqüências de caracteres, por exemplo), use o TypeScript.fonte
Temos duas matrizes a e b. o código que fez aqui é matriz, um valor é inserido na matriz b.
fonte
Tente o seguinte:
fonte
em vez da função push (), use a função concat para o IE. exemplo,
fonte
Esse é um código funcional e funciona bem:
fonte