ruby-on-rails - 将集合与相关对象分组

标签 ruby-on-rails ruby

我有一组任务,其中一个任务可以通过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 tasks and append them to the group including the linked 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>]]

关于ruby-on-rails - 将集合与相关对象分组,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/60278290/

相关文章:

ruby-on-rails - Googlebot 收到现有模板的缺失模板错误

ruby-on-rails - Rails API : Adding array of objects to json return

ruby-on-rails - 如何更新/重命名载波上传的文件?

ruby - 将每个数组元素添加到 ruby​​ 文件的行中

ruby - 使用 ruby​​ 修改 PDF

ruby - 关于Ruby collect 方法的问题

ruby-on-rails - Rails 3 App 中的用户可自定义背景

ruby-on-rails - Rails 5 api - 未定义的方法 `user_url'

ruby - 在 eventmachine 中使用 thin 和 rainbows 异步 sinatra。为什么越瘦越快?

ruby-on-rails - Heroku Amazon s3 图像 - 有时会出现 403 错误?