Follow

Keep Up to Date with the Most Important News

By pressing the Subscribe button, you confirm that you have read and are agreeing to our Privacy Policy and Terms of Use
Contact

How to reduce an array of objects to an object organised by keys

I have an array

const countries = [{
  name: "Angola",
  region: "Africa"
}, {
  name: "Spain",
  region: "Europe"
}, {
  name: "Italy",
  region: "Europe"
}]

I need the result to be:

const result = {
  Europe: [{
    name: "Spain"
  }, {
    name: "italy"
  }],
  Africa: [{
    name: "Angola"
  }]
}

I’ve tried 2 approaches:

MEDevel.com: Open-source for Healthcare and Education

Collecting and validating open-source software for healthcare, education, enterprise, development, medical imaging, medical records, and digital pathology.

Visit Medevel

  • Approach 1:
const result = countries.reduce((acc, {
  name,
  region
}) => {

  acc[region] = [...acc[region], {
    name
  }]

  return acc
}, {})
  • Approach 2:
const result = countries.reduce((acc, {
  name,
  region
}) => {
  return {
    ...acc,
    [region]: [...acc[region], {
      name
    }]
  }
}, {})

None of them work because I couldn’t find a way to spread the existing items in the array, which at a first iteration is obviously null.

Thanks

>Solution :

I wouldn’t use reduce for this at all. If you’re not doing functional programming with predefined, reusable reducer functions, reduce is just an overcomplicated loop — hard to read, easy to get wrong.

Instead, I’d just use a loop:

const result = {};
for (const { name, region } of countries) {
    let entry = result[region];
    if (!entry) {
        entry = result[region] = [];
    }
    entry.push({ name });
}
const countries = [
    {
        name: "Angola",
        region: "Africa",
    },
    {
        name: "Spain",
        region: "Europe",
    },
    {
        name: "Italy",
        region: "Europe",
    },
];

const result = {};
for (const { name, region } of countries) {
    let entry = result[region];
    if (!entry) {
        entry = result[region] = [];
    }
    entry.push({ name });
}
console.log(result);
.as-console-wrapper {
    max-height: 100% !important;
}

But since you did specifically ask for reduce, you can do it that way (any array operation can be shoehorned into a reduce):

const result = countries.reduce((result, { name, region }) => {
    let entry = result[region];
    if (!entry) {
        entry = result[region] = [];
    }
    entry.push({ name });
    return result;
}, {});
const countries = [
    {
        name: "Angola",
        region: "Africa",
    },
    {
        name: "Spain",
        region: "Europe",
    },
    {
        name: "Italy",
        region: "Europe",
    },
];

const result = countries.reduce((result, { name, region }) => {
    let entry = result[region];
    if (!entry) {
        entry = result[region] = [];
    }
    entry.push({ name });
    return result;
}, {});
console.log(result);
.as-console-wrapper {
    max-height: 100% !important;
}

Or more FP-style by creating new objects and arrays on every loop (but there’s no point in this case):

const result = countries.reduce((result, { name, region }) => {
    const entry = result[region] ?? [];
    return {
        ...result,
        [region]: [...entry, { name }],
    };
}, {});
const countries = [
    {
        name: "Angola",
        region: "Africa",
    },
    {
        name: "Spain",
        region: "Europe",
    },
    {
        name: "Italy",
        region: "Europe",
    },
];

const result = countries.reduce((result, { name, region }) => {
    const entry = result[region] ?? [];
    return {
        ...result,
        [region]: [...entry, { name }],
    };
}, {});
console.log(result);
.as-console-wrapper {
    max-height: 100% !important;
}
Add a comment

Leave a Reply

Keep Up to Date with the Most Important News

By pressing the Subscribe button, you confirm that you have read and are agreeing to our Privacy Policy and Terms of Use

Discover more from Dev solutions

Subscribe now to keep reading and get access to the full archive.

Continue reading