Combinando matrices de JavaScript - » HostIN
PorKyle Simpson es Esta es una publicación rápida y sencilla sobre técnicas…
- HostIN
- Programación
- Combinando matrices de JavaScript -
Combinando matrices de JavaScript -
PorKyle Simpson es
Esta es una publicación rápida y sencilla sobre técnicas de JavaScript. Vamos a cubrir diferentes métodos para combinar/fusionar dos matrices JS y los pros y los contras de cada enfoque.
Comenzamos con el escenario:
var a = [ 1, 2, 3, 4, 5, 6, 7, 8, 9 ];var b = [ "foo", "bar", "baz", "bam", "bun", "divertido" ];
La concatenación simple de ay bsería, obviamente,:
[1, 2, 3, 4, 5, 6, 7, 8, 9, "foo", "bar", "baz", "bam" "bun", "divertido"]
Índice de contenidos
concat(..)
El enfoque más común es:
var c = a.concat( b );a; // [1,2,3,4,5,6,7,8,9]b; // ["foo","bar","baz","bam","bun","diversión"]c; // [1,2,3,4,5,6,7,8,9,"foo","bar","baz","bam","bun","divertido"]
Como puedes ver, ces completamente nuevo arrayy representa la combinación de los dos ay blas matrices, dejándolo aintacto b. Sencillo, ¿verdad?
¿Qué pasa si ason 10.000 artículos y bson 10.000 artículos? cAhora hay 20.000 elementos, lo que básicamente equivale a duplicar el uso de memoria de ay b.
“¡No hay problema!”, dice. Simplemente los desarmamos ay bpor eso se recolectan basura, ¿verdad? ¡Problema resuelto!
a = b = nulo; // `a` y `b` pueden desaparecer ahora
Bueno. Por sólo un par de arrays pequeños, esto está bien. Pero para arrayarchivos grandes, o para repetir este proceso regularmente muchas veces, o para trabajar en entornos con memoria limitada, deja mucho que desear.
Inserción en bucle
Bien, agregamos arrayel contenido de uno al otro, usando Array#push(..):
// `b` sobre `a`for (var i=0; i b.length; i++) { a.push( b[i] );}a; // [1,2,3,4,5,6,7,8,9,"foo","bar","baz","bam","bun","fun"]b = null;
Ahora, atiene el resultado tanto del original acomo del contenido de b.
Parecería que es mejor para la memoria.
Pero, ¿y si afuera pequeño y bcomparativamente muy grande? Por razones de memoria y velocidad, probablemente desee colocar el más pequeño aen el frente ben lugar del más largo ben el final a. No hay problema, simplemente reemplaza push(..)con unshift(..)y haz un bucle en la dirección opuesta:
// `a` en `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"]a = null;
Trucos funcionales
Unfortunately, for loops are ugly and harder to maintain. Can we do any better?
Here’s our first attempt, using Array#reduce:
// `b` onto `a`:a = b.reduce( function(coll,item){ coll.push( item ); return coll;}, a );a; // [1,2,3,4,5,6,7,8,9,"foo","bar","baz","bam","bun","fun"]// or `a` into `b`:b = a.reduceRight( function(coll,item){ coll.unshift( item ); return coll;}, b );b; // [1,2,3,4,5,6,7,8,9,"foo","bar","baz","bam","bun","fun"]
Array#reduce(..) and Array#reduceRight(..) are nice, but they are a tad clunky. ES6 = arrow-functions will slim them down slightly, but it’s still requiring a function-per-item call, which is unfortunate.
What about:
// `b` onto `a`:a.push.apply( a, b );a; // [1,2,3,4,5,6,7,8,9,"foo","bar","baz","bam","bun","fun"]// or `a` into `b`:b.unshift.apply( b, a );b; // [1,2,3,4,5,6,7,8,9,"foo","bar","baz","bam","bun","fun"]
That’s a lot nicer, right!? Especially since the unshift(..) approach here doesn’t need to worry about the reverse ordering as in the previous attempts. ES6’s spread operator will be even nicer: a.push( ...b ) or b.unshift( ...a ).
But, things aren’t as rosy as they might seem. In both cases, passing either a or b to apply(..)‘s second argument (or via the ... spread operator) means that the array is being spread out as arguments to the function.
The first major problem is that we’re effectively doubling the size (temporarily, of course!) of the thing being appended by essentially copying its contents to the stack for the function call. Moreover, different JS engines have different implementation-dependent limitations to the number of arguments that can be passed.
So, if the array being added on has a million items in it, you’d almost certainly way exceed the size of the size of the stack allowed for that push(..) or unshift(..) call. Ugh. It’ll work just fine for a few thousand elements, but you have to be careful not to exceed a reasonably safe limit.
Note: You can try the same thing with splice(..), but you’ll have the same conclusions as with push(..) / unshift(..).
One option would be to use this approach, but batch up segments at the max safe size:
function combineInto(a,b) { var len = a.length; for (var i=0; i len; i=i+5000) { b.unshift.apply( b, a.slice( i, i+5000 ) ); }}
Wait, we’re going backwards in terms of readability (and perhaps even performance!). Let’s quit before we give up all our gains so far.
Summary
Array#concat(..)es el enfoque probado y verdadero para combinar dos (¡o más!) matrices. Pero el peligro oculto es que está creando una nueva matriz en lugar de modificar una de las existentes.
Hay opciones que se modifican in situ, pero tienen varias compensaciones.
Teniendo en cuenta las diversas ventajas y desventajas, quizás la mejor de todas las opciones (incluidas otras que no se muestran) sea reduce(..)y reduceRight(..).
Cualquiera que sea su elección, probablemente sea una buena idea pensar críticamente sobre su estrategia de fusión de matrices en lugar de darla por sentado.
Acerca de Kyle Simpson
Kyle Simpson es un ingeniero de software orientado a la web, ampliamente aclamado por su serie de libros “You Don't Know JS” y por casi 1 millón de horas de vistas de sus cursos en línea. El superpoder de Kyle es hacer mejores preguntas, quien cree profundamente en utilizar al máximo las herramientas mínimamente necesarias para cualquier tarea. Como “tecnólogo centrado en lo humano”, le apasiona unir a los humanos y la tecnología, haciendo evolucionar las organizaciones de ingeniería para resolver los problemas correctos, de maneras más simples. Kyle siempre luchará por las personas detrás de los píxeles.
Publicaciones de github.com
Te podría interesar...
Redirigir subdominio a URL cPanel Consejos profesionales para proteger los sitios web de WordPress Las 7 principales tendencias de alojamiento web en 2024 Desarrolladores de React.js: ¿cómo contratar y qué habilidades buscar? - Alojamiento Web | Computación en la nube | Centro de datos Centrado verticalmente con Flexbox - Utilice y proporcione imágenes complejas en WordPress 4 formas de mejorar la experiencia digital de sus clientes De contraseñas a contraseñas sin contraseña: la evolución de las contraseñas 4 formas de limpiar tu cuenta de Instagram - Web Hosting | Computación en la nube | Centro de datos
Deja una respuesta Cancelar la respuesta
Lo siento, debes estar conectado para publicar un comentario.