1

I have an array of objects that looks like this:

let stuff = [
  {
    "id": "48202847",
    "name": "Doe"
  },
  {
    "id": "17508",
    "name": "Marie"
  },
  {
    "id": "175796",
    "name": "Robert"
  },
  {
    "id": "175796",
    "name": "Ronald"
  },
]

What I want to get is a dictionary looking something like this:

{
  "D": [{"id": "48202847", "name": "Doe"}],
  "M": [{"id": "17508", "name": "Marie"}],
  "R": [{"id": "175796", "name": "Robert"}, {"id": "175796", "name": "Ronald"}]
}

Notice how all the people whose name starts with "R" are listed under one key.

This is my function that creates a dictionary with the person's name as the key:

const byId = (array) =>
  array.reduce((obj, item) => {
    obj[item.name] = item
    return obj
  }, {})

But this obviously doesn't do what I want it to. I do have some ideas of how to make this possible, but they are extremely legacy and I would love to know how to do this right. Any help is appreciated!

Christine H.
  • 143
  • 2
  • 7

3 Answers3

4

You need the first character, uppercase and an array for collecting the objects.

const byId = array =>
    array.reduce((obj, item) => {
        var key = item.name[0].toUpperCase(); // take first character, uppercase
        obj[key] = obj[key] || [];            // create array if not exists
        obj[key].push(item);                  // push item
        return obj
    }, {});

let stuff = [{ id: "48202847", name: "Doe" }, { id: "17508", name: "Marie" }, { id: "175796", name: "Robert" }, { id: "175796", name: "Ronald" }],
    result = byId(stuff)
  
console.log(result);
Nina Scholz
  • 376,160
  • 25
  • 347
  • 392
0

Here's a solution based on Set, map, reduce and filter:

let stuff = [{"id": "48202847","name": "Doe"},{"id": "17508","name": "Marie"},{"id": "175796","name": "Robert"},{"id": "175796","name": "Ronald"}];

let result = [...new Set(stuff.map(x => x.name[0]))]
  .reduce((acc, val) => {
    return acc = { ...acc,
      [val]: stuff.filter(x => x.name.startsWith(val))
    }
  }, {});

console.log(result);
connexo
  • 53,704
  • 14
  • 91
  • 128
0

Great solution Nina! Could be made a little cleaner by utilizing the spread operator.

const byId = (array) =>
  array.reduce((obj, item) => {
    var key = item.name[0].toUpperCase();
    return {
      ...obj,
      [key]: obj[key] ?  [...obj[key], item] : [item],
    }
  }, {});