JavaScript-将数组转换为映射

JavaScript-将数组转换为映射,javascript,functional-programming,ramda.js,Javascript,Functional Programming,Ramda.js,给定一组对象: var projects = [ { id: 1, name: 'Trader Portal' }, { id: 2, name: 'Risk Engine' }, ]; 将其转换为以下结构的最优雅方式是什么?基本上是ID的数组和对象的映射: { projects: [ 1, 2 ], projectMap: {

给定一组对象:

var projects = [
    {
        id: 1,
        name: 'Trader Portal'
    },
    {
        id: 2,
        name: 'Risk Engine'
    },
];
将其转换为以下结构的最优雅方式是什么?基本上是ID的数组和对象的映射:

{
    projects: [
        1,
        2
    ],
    projectMap: {
        1: {
            id: 1,
            name: 'Trader Portal'
        },
        2: {
            id: 2,
            name: 'Risk Engine'
        }
    }
}
我使用下划线(见下文或my),但有更好的方法吗?例如,是否可以使用函数式编程以更具声明性的方式实现这一点?有没有一种方法可以将代码泛化以处理任何类型的对象数组

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));

使用新的箭头函数和
map
&
reduce
数组方法,您可以进一步简化:

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;
    }, {})
};
或者,可能不需要ID数组,因为您可以轻松获得密钥:

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

var projectIds = Object.keys(projectMap);

VanillaJS实现:

var result = {projectMap: {}};
result.projects = projects.map(p => p.id);
projects.forEach(p => {
  result.projectMap[p.id] = p;
});
或者使用reduce更简单:

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

我们从空哈希开始(
{}
),并在每次reduce迭代中使用新项目(
p
)扩展进位(
c
)。

如果您对中的第二个示例感兴趣,则Ramda为此内置了一个函数,您可以使用:


爱你的答案!我希望我能把你的和杰里米贾的都标记为正确的——因为他们都是针对相同的方法(只是风格略有不同)。然而,如果只有一个选择,我将jeremija的建议标记为正确的,即我不需要结果中的ID数组-它可以从映射中派生。然而,我对你的答案投了赞成票。这确实是简短而甜蜜的。谢谢分享,@ScottSauyet。这实际上是最实用的方式
R.indexBy(R.prop('id'), projects);