Ruby Array转换的最佳方式

实现以下目标的最佳方法是什么,我在ABC下面进行了一系列操作

ABC: –

ABC:Actions, ABC:Actions:ADD-DATA, ABC:Actions:TRANSFER-DATA, ABC:Actions:EXPORT, ABC:Actions:PRINT, ABC:Detail, ABC:Detail:OVERVIEW, ABC:Detail:PRODUCT-DETAIL, ABC:Detail:EVENT-LOG, ABC:Detail:ORDERS 

我想将其格式化为:

ABC =>{Actions=> [ADD-DATA,TRANSFER-DATA,EXPORT,PRINT], Detail => [Overview, Product-detail, event-log,orders]}

可能有很多方法可以做到,但这里有一个:

 a = ["ABC:Actions", "ABC:Actions:ADD-DATA", "ABC:Actions:TRANSFER-DATA", "ABC:Actions:EXPORT", "ABC:Actions:PRINT", "ABC:Detail", "ABC:Detail:OVERVIEW", "ABC:Detail:PRODUCT-DETAIL", "ABC:Detail:EVENT-LOG", "ABC:Detail:ORDERS"] a.map { |action| action.split(":") }.inject({}) do |m, s| m[s.at(0)] ||= {} m[s.at(0)][s.at(1)] ||= [] if s.at(1) m[s.at(0)][s.at(1)] << s.at(2) if s.at(2) m end 

map调用返回一个数组,其中原始数组中的每个字符串都被拆分为由:分隔的元素数组: 。 例如[["ABC","Actions","ADD-DATA"] ... ]

然后, inject调用通过遍历每个“拆分”数组来构建哈希。 它为第一个元素(如果尚不存在)创建一个映射到空哈希,例如"ABC" => {} 。 然后它在第二个元素的哈希值中创建一个映射,如果还不存在,则为空数组,例如"ABC" => { "Detail" => [] } 。 然后它将第三个元素添加到该数组,以提供类似"ABC" => { "Detail" => ["OVERVIEW"] } 。 然后它进入下一个“拆分”数组,并以相同的方式将其添加到哈希。

我会这样做如下:

 a = ["ABC:Actions", "ABC:Actions:ADD-DATA", "ABC:Actions:TRANSFER-DATA", "ABC:Actions:EXPORT", "ABC:Actions:PRINT", "ABC:Detail", "ABC:Detail:OVERVIEW", "ABC:Detail:PRODUCT-DETAIL", "ABC:Detail:EVENT-LOG", "ABC:Detail:ORDERS"] m = a.map{|i| i.split(":")[1..-1]} # => [["Actions"], # ["Actions", "ADD-DATA"], # ["Actions", "TRANSFER-DATA"], # ["Actions", "EXPORT"], # ["Actions", "PRINT"], # ["Detail"], # ["Detail", "OVERVIEW"], # ["Detail", "PRODUCT-DETAIL"], # ["Detail", "EVENT-LOG"], # ["Detail", "ORDERS"]] m.each_with_object(Hash.new([])){|(i,j),ob| ob[i] = ob[i] + [j] unless j.nil? } # => {"Actions"=>["ADD-DATA", "TRANSFER-DATA", "EXPORT", "PRINT"], # "Detail"=>["OVERVIEW", "PRODUCT-DETAIL", "EVENT-LOG", "ORDERS"]} 

使用group_by :)这很有趣

 a = ['ABC:Actions', 'ABC:Actions:ADD-DATA', 'ABC:Actions:TRANSFER-DATA', 'ABC:Actions:EXPORT', 'ABC:Actions:PRINT', 'ABC:Detail', 'ABC:Detail:OVERVIEW', 'ABC:Detail:PRODUCT-DETAIL', 'ABC:Detail:EVENT-LOG', 'ABC:Detail:ORDERS'] result = a.map { |action| action.split(":") }.group_by(&:shift) result.each do |k1,v1| result[k1] = v1.group_by(&:shift) result[k1].each { |k2,v2| result[k1][k2] = v2.flatten } end p result {"ABC"=>{"Actions"=>["ADD-DATA", "TRANSFER-DATA", "EXPORT", "PRINT"], "Detail"=>["OVERVIEW", "PRODUCT-DETAIL", "EVENT-LOG", "ORDERS"]}}