javascript - 如何按子对象对对象列表进行最佳分组?
问题描述
我正在尝试通过它们共享的相似对象对一些 JavaScript 对象进行分组。我可以在 Ruby 中毫不费力地做到这一点,但是对于我的一生(有点尴尬)无法在 JS 中以线性时间解决这个问题。JS 似乎不允许对象文字作为键,至少出于减少的目的。
作为 GraphQL 查询的结果,我有这样的数据:
[
{
id: 1,
name: 'Bob',
room: {
id: 5,
name: 'Kitchen'
}
},
{
id: 3,
name: 'Sheila',
room: {
id: 5,
name: 'Kitchen'
}
},
{
id: 2,
name: 'Tom',
room: {
id: 3,
name: 'Bathroom'
}
}
]
在 UI 中,我们将按它们所在的房间显示对象。我们需要保留对房间本身的引用,否则我们只需按房间属性排序。
我想要做的是将数据重塑成这样的东西:
{
{id: 5, name: 'Kitchen'}: [{id: 1, name: 'Bob'}, {id: 3, name: 'Sheila'}],
{id: 3, name: 'Bathroom'}: [{id: 2, name: 'Tom'}]
}
如您所见,这些人按他们所在的房间分组在一起。
也可以做成这样的...
[
{ room: {id: 5, name: 'Kitchen'}, people: [{id: 1, name: 'Bob', ...}] },
{ room: {id: 3, name: 'Bathroom', people: [{id: 2, name: 'Tom'}]
]
不管结果如何,我们只需要在线性时间按房间分组的人。
我已经尝试过 lodash's groupBy
,同时使用map
and reduce
,只是做for
将列表放在一起的循环等等。我很难过,因为无法使用对象文字(房间)作为哈希索引,我不知道如何通过内部对象有效地分组外部对象。
任何帮助是极大的赞赏。
更新:增加关于尝试以线性时间复杂度来做这件事的清晰度——这个 Ruby 代码的最有效等价物:
h = Hash.new { |h, k| h[k] = [] }
value.each_with_object(h) { |v, m| m[v[:room]] << v }
解决方案
lodash#groupBy
您可以使用和lodash#map
收集和转换每个组来解决此问题。此外,我们使用从数组中的每个对象lodash#omit
中删除对象。room
person
people
var result = _(data)
.groupBy('room.id')
.map(people => ({
room: { ...people[0].room },
people: _.map(people, person => _.omit(person, 'room'))
})).value();
var data = [
{
id: 1,
name: 'Bob',
room: {
id: 5,
name: 'Kitchen'
}
},
{
id: 3,
name: 'Sheila',
room: {
id: 5,
name: 'Kitchen'
}
},
{
id: 2,
name: 'Tom',
room: {
id: 3,
name: 'Bathroom'
}
}
];
var result = _(data)
.groupBy('room.id')
.map(people => ({
// make sure to create a new room object reference
// to avoid mutability
room: { ...people[0].room },
people: _.map(people, person => _.omit(person, 'room'))
})).value();
console.log(result);
<script src="https://cdnjs.cloudflare.com/ajax/libs/lodash.js/4.17.10/lodash.min.js"></script>
推荐阅读
- groovy - 为什么将参数插入双引号字符串时,Groovy 的 .equals() 在 jenkins 管道脚本中失败?
- javascript - 如何使用 Javascript 从外部 HTML 文档中按 ID 获取元素?
- laravel-5 - 访问 Eloquent 集合时使用变量
- php - 如何在 PHP 中为 zip 文件设置密码
- python - 将条目小部件中的文本附加到列表中并在 tkinter 中显示
- sed - 如何根据第 x 行的内容显示第 x-3 行和第 x-1 行?
- mysql-python - (1226,“用户 '*****' 已超过 'max_queries_per_hour' 资源(当前值:1000)”)
- node.js - 如何向 Shopify 管理员显示/发送 HTML?
- twitter-bootstrap - 在容器流体内水平居中卡片
- fetch - MailKit MessageId 返回 null