Для иерархических структур вам почти наверняка понадобится рекурсия (если вы допустите произвольную глубину). Я быстро взломал некоторый код ruby, чтобы проиллюстрировать, как вы можете достичь этого (, хотя я не сделал отступ ):
# setup the data structure
class S < Struct.new(:id, :name, :parent_id);end
class HierarchySorter
def initialize(il)
@initial_list = il
first_level = @initial_list.select{|a| a.parent_id == nil}.sort_by{|a| a.name }
@final_array = subsort(first_level, 0)
end
#recursive function
def subsort(list, indent_level)
result = []
list.each do |item|
result << [item, indent_level]
result += subsort(@initial_list.select{|a| a.parent_id == item.id}.sort_by{|a| a.name }, indent_level + 1)
end
result
end
def sorted_array
@final_array.map &:first
end
def indent_hash
# magick to transform array of structs into hash
Hash[*@final_array.map{|a| [a.first.id, a.last]}.flatten]
end
end
hs = HierarchySorter.new [S.new(1, "Cats", 2), S.new(2, "Animal", nil), S.new(3, "Tiger", 1), S.new(4, "Book", nil),
S.new(5, "Airplane", nil)]
puts "Array:"
puts hs.sorted_array.inspect
puts "\nIndentation hash:"
puts hs.indent_hash.inspect
Если ты не говоришь на рубине, я могу перестроить его в другое.
Редактировать: Я обновил код выше для вывода обеих структур данных.
Выходы:
Array:
[#<struct S id=5, name="Airplane", parent_id=nil>, #<struct S id=2, name="Animal", parent_id=nil>, #<struct S id=1, name="Cats", parent_id=2>, #<struct S id=3, name="Tiger", parent_id=1>, #<struct S id=4, name="Book", parent_id=nil>]
Indentation hash:
{5=>0, 1=>1, 2=>0, 3=>2, 4=>0}