Combine two different arrays in JavaScript

Suppose we have two arrays, the first array contains the scheduled date for some events and the second array contains the names of those events, like this ?

const dates = [
    {
        id: "1",
        date: "2017-11-07"
    },
    {
        id: "1",
        date: "2017-11-08"
    },
    {
        id: "2",
        date: "2017-11-07"
    },
    {
        id: "2",
        date: "2017-11-08"
    }
];
const names = [
    {
        id: "1",
        name: "Pervies, Peter"
    },
    {
        id: "2",
        name: "Ming, Edmund"
    }
];

We are required to write a JavaScript function that takes in two such array and combines the event names with their corresponding dates based on the id property.

Therefore, for these arrays, the output should look like ?

const output = [
    {
        id: "1",
        name: "Pervies, Peter",
        details: [
            {date: "2017-11-07"},
            {date: "2017-11-08"}
        ]
    },
    {
        id: "2",
        name: "Ming, Edmund",
        details: [
            {date: "2017-11-07"},
            {date: "2017-11-08"}
        ]
    }
]

Using forEach and Array Methods

The code for this will be ?

const dates = [
    {
        id: "1",
        date: "2017-11-07"
    },
    {
        id: "1",
        date: "2017-11-08"
    },
    {
        id: "2",
        date: "2017-11-07"
    },
    {
        id: "2",
        date: "2017-11-08"
    }
];
const names = [
    {
        id: "1",
        name: "Pervies, Peter"
    },
    {
        id: "2",
        name: "Ming, Edmund"
    }
];

const combineArrays = (dates, names) => {
    const res = [];
    dates.forEach(el => {
        const bool = !res.some(item => {
            return item.id == el.id;
        });
        if(bool){
            let combined = {};
            combined.id = el.id;
            combined.details = combined.details || [];
            combined.details.push({
                "date": el.date
            });
            res.push(combined);
        }else{
            res.find(item => {
                return item.id === el.id;
            })
            .details.push({
                "date": el.date
            });
        };
    });
    res.forEach(el => {
        const bool = names.some(item => {
            return item.id === el.id;
        });
        if(bool){
            el.name = names.find(name => {
                return name.id === el.id;
            }).name;
        };
    });
    return res;
};

console.log(JSON.stringify(combineArrays(dates, names), undefined, 4));
[
    {
        "id": "1",
        "details": [
            {
                "date": "2017-11-07"
            },
            {
                "date": "2017-11-08"
            }
        ],
        "name": "Pervies, Peter"
    },
    {
        "id": "2",
        "details": [
            {
                "date": "2017-11-07"
            },
            {
                "date": "2017-11-08"
            }
        ],
        "name": "Ming, Edmund"
    }
]

Using Map and Reduce (Alternative Approach)

Here's a more concise approach using Map for better performance:

const combineArraysOptimized = (dates, names) => {
    // Create a map for quick name lookups
    const nameMap = new Map(names.map(name => [name.id, name.name]));
    
    // Group dates by id
    const dateGroups = dates.reduce((acc, date) => {
        if (!acc[date.id]) {
            acc[date.id] = [];
        }
        acc[date.id].push({ date: date.date });
        return acc;
    }, {});
    
    // Combine names with grouped dates
    return Object.keys(dateGroups).map(id => ({
        id: id,
        name: nameMap.get(id),
        details: dateGroups[id]
    }));
};

console.log(JSON.stringify(combineArraysOptimized(dates, names), undefined, 4));
[
    {
        "id": "1",
        "name": "Pervies, Peter",
        "details": [
            {
                "date": "2017-11-07"
            },
            {
                "date": "2017-11-08"
            }
        ]
    },
    {
        "id": "2",
        "name": "Ming, Edmund",
        "details": [
            {
                "date": "2017-11-07"
            },
            {
                "date": "2017-11-08"
            }
        ]
    }
]

How It Works

The first approach uses forEach to iterate through dates and builds the result incrementally. For each date, it checks if an object with that ID already exists in the result array. If not, it creates a new object; otherwise, it adds the date to the existing object's details array.

The optimized approach uses a Map for O(1) name lookups and reduce to group dates efficiently. This method is more performant for larger datasets.

Conclusion

Both methods successfully combine arrays based on matching IDs. The optimized approach using Map and reduce is more efficient for larger datasets, while the forEach method is more readable for beginners.

Updated on: 2026-03-15T23:19:00+05:30

462 Views

Kickstart Your Career

Get certified by completing the course

Get Started
Advertisements