Search code examples
javascriptarraysobject-literal

Join two objects just like SQL inner join


I have two objects like:

countries = [
    { id: 1, name: 'India', image: 'thumb15.jpg' },
    { id: 2, name: 'Africa', image: 'thumb11.jpg' },
    { id: 3, name: 'Kenya', image: 'thumb10.jpg' }
];

cities = [
    { id: 1, name: 'Ahmedabad', country_id: 1 },
    { id: 2, name: 'Vadodara', country_id: 1 },
    { id: 3, name: 'Cairo', country_id: 2 },
    { id: 4, name: 'Kinshasa', country_id: 2 },
    { id: 5, name: 'Luanda', country_id: 2 },
    { id: 6, name: 'Nairobi', country_id: 3 },
    { id: 7, name: 'Nakuru', country_id: 3 },
    { id: 8, name: 'Mombasa', country_id: 3 },
];

I want to combine these two Objects, just like SQL have INNER JOIN

for example, I want to perform below operation (query) on the above two objects,

SELECT * from countries INNER JOIN cities ON cities.country_id = countries.id

and my expected output will look like:

expected_result = [
    { id: 1, name: "Ahmedabad", country_id: 1, country_name: "India", country_image: "thumb15.jpg" },
    { id: 2, name: "Vadodara", country_id: 1, country_name: "India", country_image: "thumb15.jpg" },
    { id: 3, name: "Cairo", country_id: 2, country_name: "Africa", country_image: "thumb11.jpg" },
    { id: 4, name: "Kinshasa", country_id: 2, country_name: "Africa", country_image: "thumb11.jpg" },
    { id: 5, name: "Luanda", country_id: 2, country_name: "Africa", country_image: "thumb11.jpg" },
    { id: 6, name: "Nairobi", country_id: 3, country_name: "Kenya", country_image: "thumb10.jpg" },
    { id: 7, name: "Nakuru", country_id: 3, country_name: "Kenya", country_image: "thumb10.jpg" },
    { id: 8, name: "Mombasa", country_id: 3, country_name: "Kenya", country_image: "thumb10.jpg" }
];

Thanks in advance.


Solution

  • It is possible to use map function and Map collection to get desired country:

    const uniqueCountries = new Map(countries.map(s => [s.id, s]));
    const result = cities.map(s => ({ ...s, 
        country_name: uniqueCountries.get(s.country_id).name }));
    

    An example:

    let countries = [
        { id: 1, name: 'India', image: 'thumb15.jpg' },
        { id: 2, name: 'Africa', image: 'thumb11.jpg' },
        { id: 3, name: 'Kenya', image: 'thumb10.jpg' }
    ];
    
    let cities = [
        { id: 1, name: 'Ahmedabad', country_id: 1 },
        { id: 2, name: 'Vadodara', country_id: 1 },
        { id: 3, name: 'Cairo', country_id: 2 },
        { id: 4, name: 'Kinshasa', country_id: 2 },
        { id: 5, name: 'Luanda', country_id: 2 },
        { id: 6, name: 'Nairobi', country_id: 3 },
        { id: 7, name: 'Nakuru', country_id: 3 },
        { id: 8, name: 'Mombasa', country_id: 3 },
    ];
    
     const uniqueCountries = new Map(countries.map(s => [s.id, s]));
     const result = cities.map(s => ({ ...s, 
         country_name: uniqueCountries.get(s.country_id).name }));
     console.log(result);

    UPDATE:

    map method creates new array from the calling array. In addition, you can add new properties to your object you want:

    let countries = [
        { id: 1, name: 'India', image: 'thumb15.jpg' },
        { id: 2, name: 'Africa', image: 'thumb11.jpg' },
        { id: 3, name: 'Kenya', image: 'thumb10.jpg' }
    ];
    
    const countriesWithShortCountryNames = countries.map(s=> ({...s, 
       shortName: s.name.substring(0, 3)}))
    console.log(countriesWithShortCountryNames)

    Map collection:

    The Map object holds key-value pairs and remembers the original insertion order of the keys.