简体   繁体   English

如何将对象列表转换为键控数组/对象?

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

I'm trying to write code using Ramda to produce a new data structure, using only the id and comment keys of the original objects.我正在尝试使用 Ramda 编写代码来生成一个新的数据结构,只使用原始对象的idcomment键。 I'm new to Ramda and it's giving me some fits, although I have experience with what I think is similar coding with Python.我是 Ramda 的新手,它给了我一些配合,尽管我有经验与 Python 类似的编码。

Given the following initial data structure…给定以下初始数据结构...

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

I want to transform it into this…我想把它变成这个……

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

I found the following example in the Ramda cookbook that comes close…在接近的 Ramda 食谱中找到了以下示例……

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

But values it returns includes the whole original object as the values…但它返回的值包括整个原始 object 作为值......

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

How can I reduce the values down to the value of their comment key only?我怎样才能将值减少到他们的comment键的值?

I don't need to use the code I got from the cookbook.不需要使用从食谱中获得的代码。 If anyone can suggest some code that will give the results I'm looking for that's also better (simpler, shorter, or more efficient) than the example here, I'll be happy to use that instead.如果有人可以提出一些代码来提供我正在寻找的结果,那么它也比这里的示例更好(更简单、更短或更高效),我很乐意使用它。

If you don't mind, you don't need to use Ramda for that, pure JS can handle it nicely:如果你不介意,你不需要为此使用 Ramda,纯 JS 可以很好地处理它:

You can use a combination of Object.values() , to get all values of your first object ( commentData ) and .forEach() (or even .map() , but slower), in the array that results from Object.values to insert values into a new object dynamically. You can use a combination of Object.values() , to get all values of your first object ( commentData ) and .forEach() (or even .map() , but slower), in the array that results from Object.values to将值动态插入到新的 object 中。

 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)

But, if you want an one-liner, you can go with Object.fromEntries() after returning arrays of key/value from .map() based on id and comment , like below:但是,如果你想要一个单线,你可以 go 和Object.fromEntries() .map()返回id后返回 arrays 来自 idmap 和comment :()

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

A Ramda one-liner would be 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>

But that doesn't seem a lot cleaner than (a slight tweak to) the suggestion in epascarello's comment:但这似乎并不比 epascarello 评论中的建议(稍微调整一下)干净得多:

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

or a similar version I would write, if it didn't cause any performance issues:或我会写的类似版本,如果它不会导致任何性能问题:

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

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM