Suponiendo que tengo una matriz que tiene un tamaño de N
(donde N > 0
), ¿hay una forma más eficiente de anteponer a la matriz que no requeriría O (N + 1) pasos?
En el código, esencialmente, lo que estoy haciendo actualmente es
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
fuente
fuente
Respuestas:
No estoy seguro de que sea más eficiente en términos de big-O, pero ciertamente usar el
unshift
método es más conciso:[Editar]
Este punto de referencia jsPerf muestra que
unshift
es decentemente más rápido en al menos un par de navegadores, independientemente de un posible rendimiento de big-O diferente si está de acuerdo con modificar la matriz en el lugar. Si realmente no puede mutar la matriz original, entonces haría algo como el fragmento a continuación, que no parece ser apreciablemente más rápido que su solución:[Editar 2]
Para completar, la siguiente función se puede utilizar en lugar del ejemplo de OP
prependArray(...)
para aprovechar elunshift(...)
método Array :fuente
prepend
"unshift
"?unshift
suena más apropiado para una operación de matriz de este tipo (mueve los elementos ... más o menos físicamente).prepend
sería más apropiado para las listas vinculadas, donde literalmente antepone elementos.push
yunshift
ambos contienenu
, mientras quepop
yshift
no tienen.Con ES6, ahora puede usar el operador de propagación para crear una nueva matriz con sus nuevos elementos insertados antes que los elementos originales.
Actualización 2018-08-17: Rendimiento
Tenía la intención de que esta respuesta presentara una sintaxis alternativa que creo que es más memorable y concisa. Cabe señalar que, según algunos puntos de referencia (ver esta otra respuesta ), esta sintaxis es significativamente más lenta. Esto probablemente no va a importar a menos que esté haciendo muchas de estas operaciones en un bucle.
fuente
unshift
Si está anteponiendo una matriz al frente de otra matriz, es más eficiente usarla
concat
. Entonces:Pero esto seguirá siendo O (N) en el tamaño de oldArray. Aún así, es más eficiente que iterar manualmente sobre oldArray. Además, dependiendo de los detalles, puede ayudarlo, porque si va a anteponer muchos valores, es mejor colocarlos primero en una matriz y luego concat oldArray al final, en lugar de anteponer cada uno individualmente.
No hay forma de hacerlo mejor que O (N) en el tamaño de oldArray, porque las matrices se almacenan en la memoria contigua con el primer elemento en una posición fija. Si desea insertar antes del primer elemento, debe mover todos los demás elementos. Si necesita una solución, haga lo que dijo @GWW y use una lista vinculada o una estructura de datos diferente.
fuente
unshift
. Pero tenga en cuenta que a) que muta oldArray mientrasconcat
que no lo hace (por lo que cuál es mejor para usted depende de la situación), yb) solo inserta un elemento.[0]
), mientras que unshift la está mutando en el lugar. Pero ambos deberían ser O (N). También aplaude el enlace a ese sitio, parece muy útil.Si desea anteponer una matriz (a1 con una matriz a2), puede usar lo siguiente:
fuente
Si necesita preservar la matriz anterior, divida la antigua y desplace los nuevos valores al comienzo de la división.
fuente
Tengo algunas pruebas nuevas de diferentes métodos de prepending. Para matrices pequeñas (<1000 elems), el líder es para ciclo acoplado con un método push. Para grandes matrices, el método Unshift se convierte en el líder.
Pero esta situación es real solo para el navegador Chrome. En Firefox, unshift tiene una optimización impresionante y es más rápido en todos los casos.
La propagación de ES6 es más de 100 veces más lenta en todos los navegadores.
https://jsbench.me/cgjfc79bgx/1
fuente
Hay un método especial:
Pero si desea anteponer varios elementos a la matriz, sería más rápido utilizar dicho método:
fuente
Array.prototype.unshift.apply(a,b);
Ejemplo de anteponer en el lugar:
fuente
Llamar
unshift
solo devuelve la longitud de la nueva matriz. Entonces, para agregar un elemento al principio y devolver una nueva matriz, hice esto:o simplemente con operador de propagación:
De esta manera, la matriz original permanece intacta.
fuente