Based on your follow up comments, you're only running this once when the app loads, but you may have 10k+ items, so performance is a concern. Your current algorithm is quadratic and uses unnecessary passes.
Generally, you want to filter first, then map. The reason is that mapping first results in processing a bunch of items you may well be throwing away in the filter step. Throw away unwanted items, then map them into the desired format later.
.filter(Boolean) at the end of a chain is an antipattern. Generally, it's a lazy way to remove falsey values that could have been more properly handled earlier in the chain.
Even though you're only doing one pass, I'd still use a lookup table to avoid repeated loops over the inner array:
const employees = [
{name: 'Alice', department_id: 12},
{name: 'Bob', department_id: 13},
{name: 'Chris', department_id: 13},
{name: 'Dan', department_id: 14},
{name: 'Eve', department_id: null}
];
const departments = [
{department_id: 12, name: 'Sales'},
{department_id: 13, name: 'Marketing'},
{department_id: 14, name: 'Engineering'},
{department_id: 15, name: 'Accounting'},
{department_id: 16, name: 'Operations'}
];
const departmentsById = Object.groupBy(departments, e => e.department_id);
const ij1 = employees.reduce((a, e) => {
const d = departmentsById[e.department_id];
if (d) {
a.push({
employee_name: e.name,
employee_department_id: e.department_id,
department_id: d.department_id,
department_name: d.name,
});
}
return a;
}, []);
console.log(ij1);
Assuming O(1) lookups, the time complexity is now O(n + m) rather than O(nm).
Note that I've avoided filter and map entirely in favor of a single reduce. I prefer avoiding reduce in favor of a filter and map pair, but in this case, reduce allows us to avoid a second pass over the data, so it's a worthwhile performance tradeoff.
I'll keep _ in the variable names because that's probably how your API is returning the data, but keep in mind this isn't standard JS style. Normalize to camelCase rather than snake_case as soon as possible. ij1 is also a poor variable name--1 looks like l and I, and i and j are usually used for indexes, but I assume you picked this due to some domain-specific reason that makes sense from the context. Nonetheless, there should be another option.