2013-01-21 49 views
0

我在Ruby中有以下數據結構(其中鍵是字符串,值是數組)。跨多個陣列的一致排序

X = { "id": [2, 4, 1], "name": ["a", "b", "c"], "time": [1, 0, 2]} 

我想排序與字段「時間」相關聯的數組,但我希望所有其他數組以一致的方式排序。例如:排序後,X應該看起來像這樣。

X = {"id": [4, 2, 1], "name": ["b", "a", "c"], "time": [0, 1, 2]} 

我以一種非常醜陋的方式解決了這個問題(因爲我不知道該怎麼做)。我所做的就是創建一個時間副本,然後編號和時間,然後對其進行排序,然後壓縮名稱和time_copy並對其進行排序。然後解壓縮。我很確定這是一個可怕的方式來做到這一點。其他人能教我一個更好的方法嗎?

+0

它應該排序成b,a,然後c? –

+0

是的。如果您排序時間,並且您按照相同的順序對名稱數組進行排序,則應該得到b,a,c。 – sga001

+1

哦,我現在看到。這個數據_really_應該位於頂層數組中,下面有哈希值。 '[{id:2,name:'a',time:1},...]'。它將變得更有意義,並且更容易合作。 –

回答

1

使用@ tokland回答another question並將values_at應用於結果:

h = { id: [2, 4, 1], name: ["a", "b", "c"], time: [1, 0, 2]} 

time_indices = h[:time].each_with_index.sort_by(&:first).map(&:last) 
h.values.each{|ar| ar.replace(ar.values_at(*time_indices))} 
#=> {:id=>[4, 2, 1], :name=>["b", "a", "c"], :time=>[0, 1, 2]} 
+0

這是排序的權利,但它失去了它的結構。操作之後不再是散列。難道我做錯了什麼? – sga001

+0

不知道。我在Ruby 1.9上,它_does_改變'h'的值;根據最後,評論,線。 – steenslag

+0

你確定應該使用'each_with_index'嗎?我認爲它應該是'map.with_index'。 – sawa

2

我認爲你應該認真考慮如果三段數據應該屬於一起,你應該認真考慮將你的數據結構從一個數組哈希變成一個哈希數組。否則,您可能會遇到各種麻煩(例如,如果您不小心使陣列長度不等,會發生什麼情況) - 事實上,正如您發現的那樣,它會使分類變得相當困難。

如果你被卡住哈希作爲輸入格式,你可以轉換如下

hash = {id: [2, 4, 1], name: ["a", "b", "c"], time: [1, 0, 2]} 
array = hash.map{|k,v| [k].product(v)}.transpose.map{|h| Hash[h]} 
# => [{id: 2, name: "a", time: 1}, ...] 

在哈希表格式的數組,你可以排序字段非常容易

array.sort_by{|h| h[:time]} 
0

與steenslag幾乎相同,但我認爲應該使用map.with_index

permutation = X["time"].map.with_index{|*xi| xi}.sort_by(&:first).map(&:last) 
X.values.each{|a| a.replace(a.values_at(*permutation))}