DEV Community

Cover image for Cómo evitar bucles anidados en JavaScript
Jordi Ayala
Jordi Ayala

Posted on • Updated on • Originally published at asjordi.dev

Cómo evitar bucles anidados en JavaScript

Cuando tenemos dos arreglos y queremos combinarlos, podemos usar un bucle anidado. Pero, ¿qué pasa si cada arreglo tiene demasiados elementos? ¿Cómo podemos evitar los bucles anidados en JavaScript?

En este caso tenemos dos arreglos, el arreglo carros y el arreglo precios. En el primer arreglo tenemos los atributos modelo y marca y en el segundo arreglo tenemos los atributos precio y marca.

const carros = [
  {modelo: 2020, marca: 'Ford'},
  {modelo: 2019, marca: 'Chevrolet'},
  {modelo: 2018, marca: 'Toyota'},
  {modelo: 2017, marca: 'Nissan'},
  {modelo: 2016, marca: 'Hyundai'},
  {modelo: 2015, marca: 'Mazda'},
  {modelo: 2014, marca: 'Honda'},
  {modelo: 2013, marca: 'Subaru'}
];

const precios = [
  {precio: 30000, marca: 'Ford'},
  {precio: 25000, marca: 'Chevrolet'},
  {precio: 20000, marca: 'Toyota'},
  {precio: 15000, marca: 'Nissan'},
  {precio: 10000, marca: 'Hyundai'},
  {precio: 8000, marca: 'Mazda'},
  {precio: 7000, marca: 'Honda'},
  {precio: 6000, marca: 'Subaru'}
];
Enter fullscreen mode Exit fullscreen mode

Si necesitamos saber los precios de los carros que tenemos en el arreglo carros se deben relacionar ambos arreglos, para esto podemos usar un bucle anidado como solución.

const carrosConPrecio = carros.map(carro => {
  const precio = precios.find((precioMap) => {
    return precioMap.marca === carro.marca
  }).precio 
  return {
    ...{...carro, precio}
  }
});

// output
[
  { modelo: 2020, marca: 'Ford', precio: 30000 },
  { modelo: 2019, marca: 'Chevrolet', precio: 25000 },
  { modelo: 2018, marca: 'Toyota', precio: 20000 },
  { modelo: 2017, marca: 'Nissan', precio: 15000 },
  { modelo: 2016, marca: 'Hyundai', precio: 10000 },
  { modelo: 2015, marca: 'Mazda', precio: 8000 },
  { modelo: 2014, marca: 'Honda', precio: 7000 },
  { modelo: 2013, marca: 'Subaru', precio: 6000 }
]
Enter fullscreen mode Exit fullscreen mode

En el código anterior, primero usamos el método map para recorrer el arreglo carros y luego usamos el método find para recorrer el arreglo precios y encontrar el precio del carro.

Este código funciona, pero si tenemos muchos elementos en los arreglos, el código se vuelve muy lento, por ejemplo, las iteraciones que se hacen en el bucle anidado son 36 en un principio. Si los comienzan a aumentar, el código se vuelve relativamente lento.

Una solución para reducir el numero de iteraciones es realizar una búsqueda por referencia en lugar de una búsqueda iterativa. Para ello se debe transformar el arreglo precios en un objeto.

const nuevaListaPrecios = precios.reduce((acc, act) => {
  return {
    ...acc,
    [act.marca]: act.precio
  };
}, {});
Enter fullscreen mode Exit fullscreen mode

Obtenemos el siguiente objeto.

{
  Ford: 30000,
  Chevrolet: 25000,
  Toyota: 20000,
  Nissan: 15000,
  Hyundai: 10000,
  Mazda: 8000,
  Honda: 7000,
  Subaru: 6000
}
Enter fullscreen mode Exit fullscreen mode

Ahora podemos usar el objeto nuevaListaPrecios para obtener el precio de los carros a partir del método map.

const carrosConPrecioActual = carros.map(carro => {
  const precio = nuevaListaPrecios[carro.marca];
  return {
    ...{...carro, precio}
  }
});
Enter fullscreen mode Exit fullscreen mode

Como se observa, la diferencia esta en la forma en que se realiza la búsqueda, en el primer caso se realiza una búsqueda iterativa y en el segundo caso se realiza una búsqueda por referencia o por llave (key).

Por lo tanto, el código anterior es mucho más rápido que el código con el bucle anidado obteniendo el mismo resultado, con solo realizar 16 iteraciones respecto a las 36 que se realizaban en el primer caso.

Top comments (0)