我有一组任务
,其中一个任务可以通过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>]]
我最初的想法是
- partition on
runs_with
.- create a group for each
task
that can run alone.- loop through the other
task
s and append them to the group including the linkedtask
.
想知道是否有更惯用的方法来对它们进行分组。
最佳答案
这是我的处理方法。给定一个 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>]]
关于ruby-on-rails - 将集合与相关对象分组,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/60278290/