排序嵌套数据结构

时间:2017-04-07 17:08:20

标签: ruby ruby-on-rails-3

给定嵌套哈希(见下文),我想对具有':position'属性的兄弟姐妹进行排序。

在下面的哈希中,您可以看到child和child_child属性是一个数组但是位置没有被排序。

{:parent=>
      [{:id=>"29637484-4d39-4828-bebc-52e4ecb12250",
        :extra_data=>"parent_extra_data_1two",
        :position=>2,
        :resource_id=>"parent_resource_id_1two",
        :child=>
         [{:id=>"57c9dab3-f091-48e7-85a7-4a8a3c4782a6", :extra_data=>"child_extra_data_1two", :position=>2, :resource_id=>"child_resource_id_2two"},
          {:id=>"86b60506-f431-41f4-8555-30a83e9296f9",
           :extra_data=>"child_extra_data_1",
           :position=>1,
           :resource_id=>"child_resource_id_1",
           :child_child=>
            [{:id=>"04bb9af2-eac8-4fcf-8253-38b0ccb538c2", :extra_data=>"child_child_extra_data_one", :position=>1, :resource_id=>"child_child_one"},
             {:id=>"94947cc4-e27a-4f79-b585-f26db7ce4e66", :extra_data=>"child_child_extra_data_three", :position=>3, :resource_id=>"child_child_three"},
             {:id=>"98fe0b96-a8cd-488b-bf00-9d48633355d3", :extra_data=>"child_child_extra_data_two", :position=>2, :resource_id=>"child_child_two"}]}]}]}

会变成

{:parent=>
      [{:id=>"29637484-4d39-4828-bebc-52e4ecb12250",
        :extra_data=>"parent_extra_data_1two",
        :position=>2,
        :resource_id=>"parent_resource_id_1two",
        :child=>
         [{:id=>"86b60506-f431-41f4-8555-30a83e9296f9",
           :extra_data=>"child_extra_data_1",
           :position=>1,
           :resource_id=>"child_resource_id_1",
           :child_child=>
              [{:id=>"04bb9af2-eac8-4fcf-8253-38b0ccb538c2", :extra_data=>"child_child_extra_data_one", :position=>1, :resource_id=>"child_child_one"},
              {:id=>"98fe0b96-a8cd-488b-bf00-9d48633355d3", :extra_data=>"child_child_extra_data_two", :position=>2, :resource_id=>"child_child_two"},
              {:id=>"94947cc4-e27a-4f79-b585-f26db7ce4e66", :extra_data=>"child_child_extra_data_three", :position=>3, :resource_id=>"child_child_three"}]},
          {:id=>"57c9dab3-f091-48e7-85a7-4a8a3c4782a6", 
          :extra_data=>"child_extra_data_1two", 
          :position=>2, 
          :resource_id=>"child_resource_id_2two"
          }]}]}

2 个答案:

答案 0 :(得分:0)

在递归函数中这是一个有趣的练习,你真的应该尝试解决这些问题,因为它们肯定会提高你的技能。

def sort_me(data)
  if data.is_a? Array
    data.sort_by! { |h| h[:position] }
    data.map { |i| sort_me(i) }
  elsif data.has_key? :child
    if data[:child].is_a? Array
      data[:child].map { |i| sort_me(i) }
    end
    return data[:child].sort_by! { |h| h[:position] }
  elsif data.has_key? :child_child
    return data[:child_child].sort_by! { |h| h[:position] }
  end
  return data
end

puts sort_me(data[:parent]).to_yaml

YAML结果(对眼睛更容易)

---
- :id: 29637484-4d39-4828-bebc-52e4ecb12250
  :extra_data: parent_extra_data_1two
  :position: 2
  :resource_id: parent_resource_id_1two
  :child:
  - :id: 86b60506-f431-41f4-8555-30a83e9296f9
    :extra_data: child_extra_data_1
    :position: 1
    :resource_id: child_resource_id_1
    :child_child:
    - :id: 04bb9af2-eac8-4fcf-8253-38b0ccb538c2
      :extra_data: child_child_extra_data_one
      :position: 1
      :resource_id: child_child_one
    - :id: 98fe0b96-a8cd-488b-bf00-9d48633355d3
      :extra_data: child_child_extra_data_two
      :position: 2
      :resource_id: child_child_two
    - :id: 94947cc4-e27a-4f79-b585-f26db7ce4e66
      :extra_data: child_child_extra_data_three
      :position: 3
      :resource_id: child_child_three
  - :id: 57c9dab3-f091-48e7-85a7-4a8a3c4782a6
    :extra_data: child_extra_data_1two
    :position: 2
    :resource_id: child_resource_id_2two

答案 1 :(得分:0)

@ddubs再次感谢递归的想法。非常具有挑战性,因为我之前从未使用过递归。

def sort_tree(tree)
    tree.each_key.map { |atr|
        if obj_keys.include? atr #obj_keys is an array of symbols [:parent, child, child_child]
            tree[atr].sort_by!{|q| q[:position]}
            tree[atr].map! {|q| sort_tree(q)}
        end
        {atr => tree[atr]}
    }.reduce(:merge)
end