2017-08-26 84 views
1

我看到幾個職位對數組排序是哈希值的價值,但我想排序數組的數組,它是一個哈希值。 我有一個哈希,看起來像這樣:排序數組,它是一個哈希

h = { 
     "pets"=>[["dog", 1], ["cat", 2]], 
     "fruits"=>[["orange", 1], ["apple", 2]] 
    } 

我想根據內的陣列的第一元件(串)進行排序數組的數組。 所以我希望得到的結果是

{ 
    "pets"=>[["cat", 2], ["dog", 1]], 
    "fruits"=>[["apple", 2], ["orange", 1]] 
} 

這就是我現在所擁有的:

h.map do |key, value| 
    value.sort_by! { |x, y| x[0] <=> y[0] } 
end 

但這只是返回原始數組。我需要改變什麼? 謝謝!

回答

1

的一個問題,我看到的是,你正試圖map您的哈希值。這將始終返回一個數組。

在這種情況下,你會得到這樣的事情: [[["cat", 2], ["dog", 1]], [["apple", 2], ["orange", 1]]]

如果要修改到位的哈希值,你可以這樣做:

h.each { |key, value| h[key] = value.sort_by { ... } } 

然後h將是新的散列,按照您的期望排序。 或者你可以將其設置爲另一個變量:

new_hash = h.each { |key, value| value.sort_by! { ... } } 

下,它看起來像你混淆sortsort_by。 (很容易做到) 當您使用sort,你通過這兩個變量在塊分配給被比較的值。 (在你的情況下,數組["dog", 1]是一個參數,而另一個將是另一個數組來比較它,就像["cat", 2]) 然而,sort_by希望你做的計算,以確定它的位置是在新的秩序。通常,sort_by只接受一個參數,但因爲您正在處理數組(並且因爲Ruby處理元組的方式),所以當您告訴sort_by接受2個參數(xy)時,它們將設置爲您的第一個和第二個值陣列。 (x == "dog"y == 1

所以,你來到這裏2種選擇:保持你的塊相同,切換你的枚舉法sort,或者切換到sort_by和更改塊:

sort

h.each { |key, value| h[key] = value.sort! { |x, y| x[0] <=> y[0] } } 

sort_by

h.each { |key, value| h[key] = value.sort_by! { |x, y| y } } # In this case, `y` is the second value in your arrays, which is the integer 
+1

就叫''通過散列#map'回到獲得哈希回陣列上to_h'。 – mudasobwa

3
h.merge(h) { |*, n| n.sort } 
    #=> {"pets"=>[["cat", 2], ["dog", 1]], "fruits"=>[["apple", 2], ["orange", 1]]} 

這不修改h

這使用Hash#merge的形式,它使用一個塊來確定兩個散列中正在合併的鍵的值,這裏是所有鍵。該塊有三個塊變量,公共密鑰k,k的值爲「舊散列」,o,「新」散列值爲kn(這裏on當然是相等的。)I'米只使用最後這些變量的,所以我已經表達了塊變量爲|*, n|,而不是|k, o, n|詳見文檔

不發生變異h另一種方法:。

h.each_key.zip(h.each_value.map(&:sort)).to_h 
    #=> {"pets"=>[["cat", 2], ["dog", 1]], "fruits"=>[["apple", 2], ["orange", 1]]} 

這可以改爲寫成

h.keys.zip(h.values.map(&:sort)).to_h 
+1

傑出的合併使用,Cary。謝謝,我真的很高興看到這一點。在後面的例子中'h [k] .sort!'應該足夠了。 – mudasobwa

+0

@mudasobwa,很好的建議。我做了改變。 –

+0

minor nitpick,可以使用'each_key'而不是'keys.each',可能只是一個樣式首選項,但它是一個東西,因爲你正在排序,所以還有'each_value' –

3

不可改變的版本,無副作用:

h.map { |k, v| [k, v.sort_by(&:first)] }.to_h