ruby-on-rails - 将集合与相关对象分组
问题描述
我有一组s,其中一个任务可以通过如下所示task
的字段链接到另一个任务。runs_with
<Task id: 'abc', name: 'paint the fance', progressive: 1, runs_with: nil>
<Task id: 'def', name: 'mow the lawn', progressive: 2, runs_with: 1>
<Task id: 'ghi', name: 'wash the dishes', progressive: 3, runs_with: nil>
<Task id: 'xyz', name: 'take out the trash', progressive: 4, runs_with: 3>
<Task id: 'qur', name: 'wash the car', progressive: 5, runs_with: 2>
<Task id: 'gbj', name: 'walk the dog', progressive: 6, runs_with: 3>
现在我需要对它们进行分组,以便所有链接的最终都在一个组(一个数组)中。
[[<Task id: 'abc', name: 'paint the fance', progressive: 1, runs_with: nil>,
<Task id: 'def', name: 'mow the lawn', progressive: 2, runs_with: 1>,
<Task id: 'qur', name: 'wash the car', progressive: 5, runs_with: 2>],
[<Task id: 'ghi', name: 'wash the dishes', progressive: 3, runs_with: nil>,
<Task id: 'xyz', name: 'take out the trash', progressive: 4, runs_with: 3>,
<Task id: 'gbj', name: 'walk the dog', progressive: 6, runs_with: 3>]]
我最初的想法是
- 上的分区
runs_with
。task
为每个可以单独运行的组创建一个组。- 遍历其他
task
s 并将它们附加到包含链接的组中task
。
想知道是否有任何更惯用的方式来对它们进行分组。
解决方案
这是我将如何处理它。给定一个Task
类和一组任务:
class Task
ATTRIBUTES = [:id, :name, :progressive, :runs_with]
attr_accessor *ATTRIBUTES
include ActiveModel::Model
def inspect
'<Task %s>' % ATTRIBUTES.map { |a| '%s: %s' % [a, send(a).inspect] }.join(', ')
end
end
tasks = [
Task.new(id: 'abc', name: 'paint the fance', progressive: 1, runs_with: nil),
Task.new(id: 'def', name: 'mow the lawn', progressive: 2, runs_with: 1),
Task.new(id: 'ghi', name: 'wash the dishes', progressive: 3, runs_with: nil),
Task.new(id: 'xyz', name: 'take out the trash', progressive: 4, runs_with: 3),
Task.new(id: 'qur', name: 'wash the car', progressive: 5, runs_with: 2),
Task.new(id: 'gbj', name: 'walk the dog', progressive: 6, runs_with: 3)
]
我将创建一个散列,其中每个值都是包装在数组中的任务,其编号为键:
hash = tasks.group_by(&:progressive)
{
1 => [<Task id: "abc", name: "paint the fance", progressive: 1, runs_with: nil>],
2 => [<Task id: "def", name: "mow the lawn", progressive: 2, runs_with: 1>],
3 => [<Task id: "ghi", name: "wash the dishes", progressive: 3, runs_with: nil>],
4 => [<Task id: "xyz", name: "take out the trash", progressive: 4, runs_with: 3>],
5 => [<Task id: "qur", name: "wash the car", progressive: 5, runs_with: 2>],
6 => [<Task id: "gbj", name: "walk the dog", progressive: 6, runs_with: 3>]
}
然后我将遍历原始tasks
数组,并为每个具有runs_with
属性的任务,将任务的数组与相应任务的数组合并为一个:
tasks.each do |task|
if task.runs_with
hash[task.runs_with].concat(hash[task.progressive])
hash[task.progressive] = hash[task.runs_with]
end
end
这将有效地合并数组并减少沿途的数组数量。然而,哈希将引用来自不同键的那些(相同的)数组,所以最后我们必须获取哈希的唯一值:
hash.values.uniq
#=> [[<Task id: "abc", name: "paint the fance", progressive: 1, runs_with: nil>,
# <Task id: "def", name: "mow the lawn", progressive: 2, runs_with: 1>,
# <Task id: "qur", name: "wash the car", progressive: 5, runs_with: 2>],
# [<Task id: "ghi", name: "wash the dishes", progressive: 3, runs_with: nil>,
# <Task id: "xyz", name: "take out the trash", progressive: 4, runs_with: 3>,
# <Task id: "gbj", name: "walk the dog", progressive: 6, runs_with: 3>]]
推荐阅读
- javascript - Tabulator.js - IE11 - “错误:未指定的错误......”
- ios - 无法在 iOS 14(模拟器和设备)上使用 VideoPlayer 播放 HEVC
- firebase - 我无法部署 Firebase 功能,因为我没有“服务帐户用户”角色
- python - youtube页面使用selenium向下滚动,python
- python - 将数据框列值编辑为特定格式
- javascript - 命名空间“google.maps”没有导出成员“MouseEvent”
- java - 未设置 X11 DISPLAY 变量。如何使用 java 从 linux 中的剪贴板获取数据?
- python - 如何将 python time.time() 转换为日期格式以进行 sql 插入
- asp.net-core - 从 Entity Framework Core 中的 cookie 和基本路径创建数据库上下文
- javascript - 从资产文件夹打开本地 html 时,window.open() 弹出窗口被广告拦截器阻止,如果文件没有 .html 扩展名,则工作正常