user88432
user88432

Reputation: 417

Should I use reduce for mapping?

Just wondering should I stick with reduce for mapping?

The code is quite long. Is there a way to refactor this to look a bit cleaner?

const items = [
 { Name: "one" },
 { error: true, code: "INVALID 1" },
 { Name: "two" },
 { Name: "three" },
 { error: true, code: "INVALID OTHER" },
]

const filtered = items.reduce((acc, item) => {
  if (item.error === true) {
    if (!acc.errors) {
      acc.errors = [];
    }

    acc.errors.push(item);

    return acc;
  }

  if (!acc.items) {
    acc.items = [];
  }

  acc.items.push(item);

  return acc;
}, {});

console.log(filtered)

Upvotes: 1

Views: 63

Answers (2)

Jon Warren
Jon Warren

Reputation: 857

Is the only determinate of which object it falls under just whether or not the object contains an error key? If so, what about something like this:

const items = [
    { Name: "one" },
    { error: true, code: "INVALID 1" },
    { Name: "two" },
    { Name: "three" },
    { error: true, code: "INVALID OTHER" },
];

const filtered = {
    errors: items.filter(i => Object.keys(i).includes('error')),
    items: items.filter(i => !Object.keys(i).includes('error'))
}

console.log(filtered);

Upvotes: 3

Ori Drori
Ori Drori

Reputation: 192252

Since the only difference between the two parts of the reducer is the key you push to, extract the key selection, and make everything dependant on the key:

const items = [{"Name":"one"},{"error":true,"code":"INVALID 1"},{"Name":"two"},{"Name":"three"},{"error":true,"code":"INVALID OTHER"}]

const filtered = items.reduce((acc, item) => {
  const key = item.error ? 'errors' : 'items'
  
  if (!acc[key]) acc[key] = []

  acc[key].push(item)

  return acc
}, {})

console.log(filtered)

Upvotes: 2

Related Questions