2017-06-12 54 views
1

我有以下目錄樹結構的「dir paths」數組。數組中的每個元素都是包含路徑的一部分的數組,因爲它是元素。這是一個按「層次結構」排序的示例。每個元件還包括private布爾標誌作爲的Ruby on Rails的pluck方法的結果是:將目錄數組轉換爲特定的嵌套散列

[ 
    [["Dir 01"], false], 
    [["Dir 02"], true], 
    [["Dir 01", "Dir 01 01"], false], 
    [["Dir 01", "Dir 01 02"], false], 
    [["Dir 01", "Dir 01 02", "Dir 01 02 01"], false] 
] 

我需要轉換成以下數組散列結構在紅寶石:

[ 
    {:title => "Dir 01", 
     :private => false, 
     :sub_dirs => [ 
      {:title => "Dir 01 01", :private => false}, 
      {:title => "Dir 01 02", 
       :private => false, 
       :sub_dirs => [ 
        {:title => "Dir 01 02 01", :private => false} 
       ]}, 
     ]}, 
    {:title => "Dir 02", :private => true} 
] 

到目前爲止我曾嘗試此代碼:

arr = Array.new 
dirs.each { |dir| arr << dir[0].reverse.inject({private: dir[1]}) { |a, n| { n => a } } } 

爲了產生以下的數組:

[ 
    {"Dir 01" => {:private => false}}, 
    {"Dir 01" => {:private => true}}, 
    {"Dir 01" => {"Dir 01 01" => {:private => false}}}, 
    {"Dir 01" => {"Dir 01 02" => {:private => false}}}, 
    {"Dir 01" => {"Dir 01 02" => {"Dir 01 02 01" => {:private => false}}}} 
] 

但現在我卡住了。

謝謝。

回答

2

您可以使用遞歸來獲得所需的結果。這具有可以在所需結果中嵌套任意級別的優點。

代碼

def recurse(arr) 
    arr.group_by { |a, _| a.first } 
     each_with_object([]) do |(k, a), hashes| 
     _, private = a.find { |titles,_| titles == [k] }  
     h = { title: k, private: private } 
     if a.size > 1 
      aa = a.map { |title, private| [title[1..-1], private] }. 
       reject { |title,_| title.empty? } 
      h.update(subdirs: recurse(aa)) 
     end 
     hashes << h 
     end 
end 

實例

arr = [ 
    [["Dir 01"], false], 
    [["Dir 02"], true], 
    [["Dir 01", "Dir 01 01"], false], 
    [["Dir 01", "Dir 01 02"], false], 
    [["Dir 01", "Dir 01 02", "Dir 01 02 01"], false] 
] 

recurse(arr) 
    #=> [{:title=>"Dir 01", :private=>false, 
    #  :subdirs=>[{:title=>"Dir 01 01", :private=>false}, 
    #    {:title=>"Dir 01 02", :private=>false, 
    #     :subdirs=>[{:title=>"Dir 01 02 01", :private=>false}] 
    #    } 
    #    ] 
    # }, 
    # {:title=>"Dir 02", :private=>true} 
    # ] 

arr += [ 
    [["Dir 01", "Dir 01 02", "Dir 01 02 01", "Dir 01 02 01 99"], true], 
    [["Dir 01", "Dir 01 02", "Dir 01 02 01", "Dir 01 02 01 42"], false], 
    [["Dir 01", "Dir 01 02", "Dir 01 02 02"], false], 
    [["Dir 01", "Dir 01 02", "Dir 01 02 02", "Dir 01 02 02 17"], true], 
    [["Dir 01", "Dir 01 02", "Dir 01 02 02", "Dir 01 02 02 31"], false] 
] 
    #=> [[["Dir 01"], false], 
    # [["Dir 02"], true], 
    # [["Dir 01", "Dir 01 01"], false], 
    # [["Dir 01", "Dir 01 02"], false], 
    # [["Dir 01", "Dir 01 02", "Dir 01 02 01"], false], 
    # [["Dir 01", "Dir 01 02", "Dir 01 02 01", "Dir 01 02 01 99"], true], 
    # [["Dir 01", "Dir 01 02", "Dir 01 02 01", "Dir 01 02 01 42"], false], 
    # [["Dir 01", "Dir 01 02", "Dir 01 02 02"], false], 
    # [["Dir 01", "Dir 01 02", "Dir 01 02 02", "Dir 01 02 02 17"], true], 
    # [["Dir 01", "Dir 01 02", "Dir 01 02 02", "Dir 01 02 02 31"], false]] 

recurse arr 
    #=> [ 
    # {:title=>"Dir 01", :private=>false, 
    #  :subdirs=>[ 
    #  {:title=>"Dir 01 01", :private=>false}, 
    #  {:title=>"Dir 01 02", :private=>false, 
    #  :subdirs=>[ 
    #   {:title=>"Dir 01 02 01", :private=>false, 
    #   :subdirs=>[ 
    #    {:title=>"Dir 01 02 01 99", :private=>true}, 
    #    {:title=>"Dir 01 02 01 42", :private=>false} 
    #   ] 
    #   }, 
    #   {:title=>"Dir 01 02 02", :private=>false, 
    #   :subdirs=>[ 
    #    {:title=>"Dir 01 02 02 17", :private=>true}, 
    #    {:title=>"Dir 01 02 02 31", :private=>false} 
    #   ] 
    #   } 
    #  ] 
    #  } 
    #  ] 
    # }, 
    # {:title=>"Dir 02", :private=>true} 
    # ] 

說明

(正在建設中......)

+0

感謝@卡里 - swoveland有一個良好的工作解決方案。 –