Resuelvo una prueba en la que solicitan un INNER JOIN 👨‍💻

Te enseñaré a crear una función que hará un INNER JOIN de dos arrays de objetos JSON.

21.08.2022 a las 12:44

Resuelvo una prueba en la que solicitan un INNER JOIN 👨‍💻

⚫ ¿Qué es un INNER JOIN?

⚫ Enunciado de la prueba

⚫ Código de la solución

⚫ Salida del algoritmo

Resuelvo una prueba en la que solicitan un INNER JOIN 👨‍💻

En esta prueba técnica nos piden hacen un INNER JOIN entre dos arrays de objetos JSON.

¿Qué es un INNER JOIN?

La operación INNER JOIN es muy utilizada en bases de datos SQL.

Se trata de combinar los registros de dos tablas si hay valores coincidentes en algún campo común.


Un ejemplo de consulta SQL con la operación INNER JOIN es:

SELECT CategoryName, ProductName
FROM Categories INNER JOIN Products
ON Categories.CategoryID = Products.CategoryID;

Enunciado de la prueba

Dado dos listas de objetos se pide crear una función que aceptará 3 parámetros:

  • Lista de contactos
  • Lista de asistentes a la reunión
  • Campo por el que se hará la búsqueda

La función debe devolver un listado de contactos con los datos combinados de ambas listas o arrays.


Se hace especial hincapié en que la función debe tener un buen rendimiento 🚩


Al leer buen rendimiento se me encienden alarmas de usar mientras menos bucles mejor porque la solución que de primeras se me ocurre es recorrer con un bucle el primer array y por cada item hacer otro bucle con ese item buscando en el segundo array.


El rendimiento de los bucles anidados no es bueno, así que se me ocurre que lo haré con una tabla de hash. Particularmente me encanta esta estructura de datos.


Los datos de la prueba son:

  const contacts = [
    {
      id: 7,
      email: 'michael.lawson@reqres.in',
      first_name: 'Michael',
      last_name: 'Lawson',
      avatar: 'https://reqres.in/img/faces/7-image.jpg',
    },
    {
      id: 8,
      email: 'lindsay.ferguson@reqres.in',
      first_name: 'Lindsay',
      last_name: 'Ferguson',
      avatar: 'https://reqres.in/img/faces/8-image.jpg',
    },
    {
      id: 9,
      email: 'tobias.funke@reqres.in',
      first_name: 'Tobias',
      last_name: 'Funke',
      avatar: 'https://reqres.in/img/faces/9-image.jpg',
    },
    {
      id: 10,
      email: 'byron.fields@reqres.in',
      first_name: 'Byron',
      last_name: 'Fields',
      avatar: 'https://reqres.in/img/faces/10-image.jpg',
    },
    {
      id: 11,
      email: 'george.edwards@reqres.in',
      first_name: 'George',
      last_name: 'Edwards',
      avatar: 'https://reqres.in/img/faces/11-image.jpg',
    },
    {
      id: 12,
      email: 'rachel.howell@reqres.in',
      first_name: 'Rachel',
      last_name: 'Howell',
      avatar: 'https://reqres.in/img/faces/12-image.jpg',
    },
    {
      id: 7,
      email: 'michael.lawson@reqres.in',
      first_name: 'Michael',
      last_name: 'Lawson',
      avatar: 'https://reqres.in/img/faces/7-image.jpg',
    },
    {
      id: 8,
      email: 'lindsay.ferguson@reqres.in',
      first_name: 'Lindsay',
      last_name: 'Ferguson',
      avatar: 'https://reqres.in/img/faces/8-image.jpg',
    },
    {
      id: 9,
      email: 'tobias.funke@reqres.in',
      first_name: 'Tobias',
      last_name: 'Funke',
      avatar: 'https://reqres.in/img/faces/9-image.jpg',
    },
    {
      id: 10,
      email: 'byron.fields@reqres.in',
      first_name: 'Byron',
      last_name: 'Fields',
      avatar: 'https://reqres.in/img/faces/10-image.jpg',
    },
    {
      id: 11,
      email: 'george.edwards@reqres.in',
      first_name: 'George',
      last_name: 'Edwards',
      avatar: 'https://reqres.in/img/faces/11-image.jpg',
    },
    {
      id: 12,
      email: 'rachel.howell@reqres.in',
      first_name: 'Rachel',
      last_name: 'Howell',
      avatar: 'https://reqres.in/img/faces/12-image.jpg',
    }
  ]

const meetingContacts = [
    {
      id: 1,
      email: 'michael.lawson@reqres.in',
      first_name: 'Michael',
      confirmed: true       
    },
    {
      id: 2,
      email: 'george.edwards@reqres.in',
      first_name: 'George',
      confirmed: true   
    },
    {
      id: 3,
      email: 'lindsay.ferguson@reqres.in',
      first_name: 'Lindsay',
      confirmed: true   
    }
]
  

Como podemos ver nos dan un listado de contactos y un listado de asistentes a una reunión.


Tenemos que crear una función que pasándole como parámetros los dos listados y un campo de búsqueda devuelva un listado combinando los datos comunes de ambas listas o arrays.

Código de la solución

  function innerJoin(
    firstArray: { 
      id: number, 
      email: string, 
      first_name: string, 
      last_name: string, 
      avatar: string }[], 
    secondArray: { 
      id: number, 
      email: string, 
      first_name: string, 
      confirmed:boolean }[], 
    key: 'email' | 'first_name'): Array<object> {
      const hashMap=new Map;
      firstArray.forEach(item=> hashMap.set(item[key],item));

      const result:{}[]=[];
      secondArray.forEach(item=>{        
          const getItemFromMap = hashMap.get(item[key]);
          if (!getItemFromMap) return;        
          const {id:idFirstItemArray, ...restFirstItemArray} = getItemFromMap; //uso la desesctruturación para extraer el id y poder renombrarlo
          const {id:idSecondItemArray, ...restSecondItemArray} = item; //uso la desesctruturación para extraer el id y poder renombrarlo        
          result.push({idFirstItemArray,...restFirstItemArray, idSecondItemArray, ...restSecondItemArray});
      })

      return result;
  }

  console.log(innerJoin(contacts,meetingContacts,"email")) //en el key sólo podré pasarle el email o el first_name como parámetro
  

Algo que da muchos puntos es que al tipar el parámetro de la key sólo permitirá aceptar o email o first_name que son los campos comunes. Esto evita muchos problemas de desarrollo en el futuro. Es la magia de TypeScript.


Si te fijas, como cada lista tiene su propio campo id que no coincide, lo que he hecho es (usando la desestructuración de objetos) sacar el id de cada lista y renombrarlo para posteriormente añadirlo a la solución.

Salida del algoritmo

  [LOG]: [{
    "idFirstItemArray": 7,
    "email": "michael.lawson@reqres.in",
    "first_name": "Michael",
    "last_name": "Lawson",
    "avatar": "https://reqres.in/img/faces/7-image.jpg",
    "idSecondItemArray": 1,
    "confirmed": true
  }, {
    "idFirstItemArray": 11,
    "email": "george.edwards@reqres.in",
    "first_name": "George",
    "last_name": "Edwards",
    "avatar": "https://reqres.in/img/faces/11-image.jpg",
    "idSecondItemArray": 2,
    "confirmed": true
  }, {
    "idFirstItemArray": 8,
    "email": "lindsay.ferguson@reqres.in",
    "first_name": "Lindsay",
    "last_name": "Ferguson",
    "avatar": "https://reqres.in/img/faces/8-image.jpg",
    "idSecondItemArray": 3,
    "confirmed": false
  }] 
  

Hasta luego 🖖

Servicios

Software

IoT

Digitalización

Aplicaciones móviles

Consultoría

fjmduran.com v0.1.2