Skip to main content
1 of 10
ggorlen
  • 4.2k
  • 2
  • 19
  • 28

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.

ggorlen
  • 4.2k
  • 2
  • 19
  • 28