Naresh
Naresh

Reputation: 25753

JavaScript - Converting arrays to maps

Given an array of objects:

var projects = [
    {
        id: 1,
        name: 'Trader Portal'
    },
    {
        id: 2,
        name: 'Risk Engine'
    },
];

What is the most elegant way of converting it into the following structure - essentially and array of the ids along with a map of the objects:

{
    projects: [
        1,
        2
    ],
    projectMap: {
        1: {
            id: 1,
            name: 'Trader Portal'
        },
        2: {
            id: 2,
            name: 'Risk Engine'
        }
    }
}

I did this using underscore (see below or my codepen), but is there a better way? For example can this be done in a more declarative way using functional programming? Is there a way to genericize the code to work on an array of any type of objects?

var projects = [
    {
        id: 1,
        name: 'Trader Portal'
    },
    {
        id: 2,
        name: 'Risk Engine'
    },
];

var result = {};

result.projects = _.map(projects, function(project) {
  return project.id;
});

result.projectMap = {};
_.each(projects, function(project) {
  result.projectMap[project.id] = project;
});

console.log(JSON.stringify(result));

Upvotes: 2

Views: 73

Answers (3)

Scott Sauyet
Scott Sauyet

Reputation: 50787

If you're just interested in the second example from @jeremija, then Ramda has a function built-in for this, indexBy, which you can use like this:

R.indexBy(R.prop('id'), projects);

Upvotes: 4

vp_arth
vp_arth

Reputation: 14982

VanillaJS implementation:

var result = {projectMap: {}};
result.projects = projects.map(p => p.id);
projects.forEach(p => {
  result.projectMap[p.id] = p;
});

Or even simpler with reduce:

result.projectMap = projects.reduce((c, p) => (c[p.id] = p, c), {});

We start here from empty hash {}, and extend carry(c) with new project(p) on each reduce iteration.

Upvotes: 1

jeremija
jeremija

Reputation: 2528

Using the new arrow functions, and the map & reduce Array methods, you can further simplify this:

var projects = [
    {
        id: 1,
        name: 'Trader Portal'
    },
    {
        id: 2,
        name: 'Risk Engine'
    },
];

var projectMap = {
    projects: projects.map(p => p.id),
    projectMap: projects.reduce((obj, p) => {
      obj[p.id] = p;
      return obj;
    }, {})
};

Or maybe having an array of IDs is not necessary as you can easily get just the keys:

var projectMap = projects.reduce((obj, p) => {
    obj[p.id] = p;
    return obj;
}, {});

var projectIds = Object.keys(projectMap);

Upvotes: 2

Related Questions