2017-07-19 100 views
4

是否可以通過兒童鍵的值對父散列進行排序?是否可以通過子哈希值對多維哈希進行排序?

例如:

{ 
    :a => 
     {:order => 3}, 
    :b => 
     {:order => 1}, 
    :c => 
     {:order => 2} 
} 

使出如

{ 
    :b => 
     {:order => 1}, 
    :c => 
     {:order => 2}, 
    :a => 
     {:order => 3} 
} 
+1

請記住哈希是打算作爲無序的容器。 Ruby僅支持一種排序方法:插入順序。 – tadman

回答

4

你可以將其轉換爲對的數組,使用sort_by方式來指定要排序的值,然後將其轉換回到哈希:

h = { 
    :a => 
     {:order => 3}, 
    :b => 
     {:order => 1}, 
    :c => 
     {:order => 2} 
} 

h.sort_by {|k,v| v[:order]}.to_h 
=> {:b=>{:order=>1}, :c=>{:order=>2}, :a=>{:order=>3}} 
+1

關閉,但如果這是目標,則需要將這些重新組合回哈希。 – tadman

+0

我只在事實後才注意到這一點。那時其他人已經做到了。 –

+0

這是值得修復它,因爲否則它是好的。 – tadman

4

請記住,唯一的訂單,一個Ruby哈希可以有基於插入順序。您需要創建一個新的散列(不是sort!),並按您希望的順序創建新的散列元素。

考慮:

> hash 
=> {:a=>{:order=>3}, :b=>{:order=>1}, :c=>{:order=>2}} 

您可以使用.sort_by做:

> hash.sort_by {|k, h| h[:order]}.to_h 
=> {:b=>{:order=>1}, :c=>{:order=>2}, :a=>{:order=>3}} 

您也可以使用更經典.sort與飛船<=>通過拆包與通常a,b相關的參數:

> hash.sort {|(a,ha),(b,hb)| ha[:order] <=> hb[:order] }.to_h 
=> {:b=>{:order=>1}, :c=>{:order=>2}, :a=>{:order=>3}} 

無論哪種情況,.to_h方法都會根據來自源散列的排序後的鍵值對創建新的散列。

最好