Вот как бы я подошел к этому. Учитывая класс 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)
]
Я бы создал ха sh, где каждое значение было бы задачей, заключенной в массив с номером в качестве ключа:
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
Это будет эффективно объединять массивы и сокращать количество массивов по пути. Однако ha sh будет ссылаться на эти (идентичные) массивы из разных ключей, поэтому в конце мы должны получить уникальные значения ha sh * *1014*:
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>]]