如何将对象列表变成键控 array/object?

How to turn a list of objects into a keyed array/object?

我正在尝试使用 Ramda 编写代码来生成新的数据结构,仅使用原始对象的 idcomment 键。我是 Ramda 的新手,它给了我一些适合,尽管我有我认为与 Python.

类似编码的经验

给定以下初始数据结构……

const commentData = {
  '30': {'id': 6, 'comment': 'fubar', 'other': 7},
  '34': {'id': 8, 'comment': 'snafu', 'other': 6},
  '37': {'id': 9, 'comment': 'tarfu', 'other': 42}
};

我想把它改成这样……

{
  '6': 'fubar',
  '8': 'snafu',
  '9': 'tarfu'
}

我发现以下 example in the Ramda cookbook 接近…

const objFromListWith = R.curry((fn, list) => R.chain(R.zipObj, R.map(fn))(list));
objFromListWith(R.prop('id'), R.values(commentData));

但它的值 returns 包括整个原始对象作为值…

{
  6: {id: 6, comment: "fubar", other: 7},
  8: {id: 8, comment: "snafu", other: 6},
  9: {id: 9, comment: "tarfu", other: 42}
}

我怎样才能将值减少到仅 comment 键的值?

不需要来使用我从食谱中获得的代码。如果有人可以建议一些代码来提供我正在寻找的结果并且比这里的示例更好(更简单、更短或更有效),我将很乐意改用它。

如果你不介意,你不需要使用 Ramda,纯 JS 可以很好地处理它:

您可以使用 Object.values() 的组合来获取第一个对象 (commentData) 和 .forEach()(甚至 .map(),但速度较慢)的所有值, 在 Object.values 生成的数组中动态地将值插入新对象。

const commentData = {
  '30': {'id': 6, 'comment': 'fubar', 'other': 7},
  '34': {'id': 8, 'comment': 'snafu', 'other': 6},
  '37': {'id': 9, 'comment': 'tarfu', 'other': 42}
};

let values = Object.values(commentData)
let finalObj = {};

values.forEach(x => finalObj[x.id] = x.comment)

console.log(finalObj)

但是,如果你想要一个单行,你可以在从 .map() 返回 key/value 的数组后使用 Object.fromEntries() 基于 idcomment,如下所示:

const commentData = {
  '30': {'id': 6, 'comment': 'fubar', 'other': 7},
  '34': {'id': 8, 'comment': 'snafu', 'other': 6},
  '37': {'id': 9, 'comment': 'tarfu', 'other': 42}
};

console.log(Object.fromEntries(Object.values(commentData).map(x => [x.id, x.comment])))

Ramda 单行代码是

const foo = compose(fromPairs, map(props(['id', 'comment'])), values)

const commentData = {
  '30': {'id': 6, 'comment': 'fubar', 'other': 7},
  '34': {'id': 8, 'comment': 'snafu', 'other': 6},
  '37': {'id': 9, 'comment': 'tarfu', 'other': 42}
}

console.log(
  foo(commentData)
)
<script src="//cdnjs.cloudflare.com/ajax/libs/ramda/0.26.1/ramda.js"></script>
<script>const {compose, fromPairs, map, props, values} = R           </script>

但这似乎并不比 epascarello 评论中的建议(稍微调整)更清晰:

const foo = (obj) => 
  Object.values(obj).reduce((o, v) => (o[v.id] = v.comment) && o, {})

或我会编写的类似版本,如果它不会导致任何性能问题:

const foo = (obj) => 
  Object.values(obj).reduce((o, {id, comment}) => ({...o, [id]: comment}), {})