Supondo que eu tenha uma matriz que tenha um tamanho de N
(onde N > 0
), existe uma maneira mais eficiente de preceder a matriz que não exigiria etapas O (N + 1)?
No código, essencialmente, o que estou fazendo atualmente é
function prependArray(value, oldArray) {
var newArray = new Array(value);
for(var i = 0; i < oldArray.length; ++i) {
newArray.push(oldArray[i]);
}
return newArray;
}
javascript
arrays
prepend
samccone
fonte
fonte
Respostas:
Não tenho certeza de que seja mais eficiente em termos de big-O, mas certamente o uso do
unshift
método é mais conciso:[Editar]
Esse benchmark jsPerf mostra que
unshift
é decentemente mais rápido em pelo menos alguns navegadores, independentemente do desempenho de grande O possivelmente diferente, se você estiver certo em modificar a matriz no local. Se você realmente não pode alterar a matriz original, faria algo como o snippet abaixo, que não parece ser apreciavelmente mais rápido que sua solução:[Editar 2]
Para completar, a seguinte função pode ser usada em vez do exemplo do OP
prependArray(...)
para tirar proveito dounshift(...)
método Array :fonte
prepend
"unshift
"?unshift
parece mais apropriado para essa operação de matriz (move os elementos ... mais ou menos fisicamente).prepend
seria mais apropriado para listas vinculadas, nas quais você literalmente anexa elementos.push
eunshift
ambos contêmu
, enquantopop
eshift
não têm.Com o ES6, agora você pode usar o operador de spread para criar uma nova matriz com seus novos elementos inseridos antes dos elementos originais.
Atualização 17/08/2018: Desempenho
Pretendi que esta resposta apresentasse uma sintaxe alternativa que eu acho mais memorável e concisa. Deve-se notar que, de acordo com alguns parâmetros de referência (consulte esta outra resposta ), essa sintaxe é significativamente mais lenta. Provavelmente isso não será importante, a menos que você esteja executando muitas dessas operações em um loop.
fonte
unshift
Se você estiver anexando uma matriz à frente de outra matriz, é mais eficiente usar apenas
concat
. Assim:Mas isso ainda será O (N) no tamanho do oldArray. Ainda assim, é mais eficiente do que iterar manualmente sobre o oldArray. Além disso, dependendo dos detalhes, isso pode ajudá-lo, porque se você anexará muitos valores, é melhor colocá-los em uma matriz primeiro e concatenar o oldArray no final, em vez de anexar cada um individualmente.
Não há como fazer melhor que O (N) no tamanho de oldArray, porque as matrizes são armazenadas na memória contígua com o primeiro elemento em uma posição fixa. Se você deseja inserir antes do primeiro elemento, é necessário mover todos os outros elementos. Se você precisar contornar isso, faça o que o @GWW disse e use uma lista vinculada ou uma estrutura de dados diferente.
fonte
unshift
. Mas observe que a) que modifica oldArray enquantoconcat
que não (então qual é o melhor para você depende da situação) eb) ele insere apenas um elemento.[0]
), enquanto o unshift a está mutando no local. Mas ambos devem ser O (N). Também aplaude o link para esse site - parece muito útil.Se você deseja anexar a matriz (a1 com uma matriz a2), use o seguinte:
fonte
Se você precisar preservar a matriz antiga, corte a matriz antiga e desvie o (s) novo (s) valor (es) para o início da fatia.
fonte
Eu tenho alguns testes novos de diferentes métodos de pré-anexação. Para matrizes pequenas (<1000 elems), o líder é para ciclo acoplado a um método push. Para matrizes enormes, o método Unshift se torna o líder.
Mas essa situação é real apenas para o navegador Chrome. No Firefox, o unshift tem uma otimização impressionante e é mais rápido em todos os casos.
A propagação do ES6 é 100 vezes mais lenta em todos os navegadores.
https://jsbench.me/cgjfc79bgx/1
fonte
Existe um método especial:
Mas se você quiser acrescentar vários elementos à matriz, seria mais rápido usar esse método:
fonte
Array.prototype.unshift.apply(a,b);
Exemplo de anexação no local:
fonte
A chamada
unshift
retorna apenas o comprimento da nova matriz. Então, para adicionar um elemento no começo e retornar uma nova matriz, fiz o seguinte:ou simplesmente com o operador spread:
Dessa forma, a matriz original permanece intocada.
fonte