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