2012-01-19 37 views
3

我有兩個陣列a,相同長度的b重新排序以相同的順序數組作爲另一個陣列重新排序

a = [a_1, a_2, ..., a_n] 
b = [b_1, b_2, ..., b_n] 

當我排序a使用sort_by!,的a的元件將被佈置在不同的順序:

a.sort_by!{|a_i| some_condition(a_i)} 

我怎樣才能重新排序以相同的順序/重排的a重新排序b?例如,如果asort_by!

[a_3, a_6, a_1, ..., a_i_n] 

那麼我想

[b_3, b_6, b_1, ..., b_i_n] 

編輯

我需要做的很到位(即,保留的a OBJECT_ID,b) 。到目前爲止給出的兩個答案中給出的排序陣列是有用,:

a_sorted 
b_sorted 

我可以做

a.replace(a_sorted) 
b.replace(b_sorted) 

,但如果可能的話,我想直接做。如果不是,我會接受已經給出的答案之一。

+0

如何爲b定義'相同的順序'?舊索引 - >新索引對於b的每個元素都是等效的? –

+0

@MarkThomas我將它定義爲具有相同的置換矩陣(http://en.wikipedia.org/wiki/Permutation_matrix)。 – sawa

+0

您是否需要保存置換矩陣(或向量,因爲它可能在這種情況下)? –

回答

10

一種方法是將兩個數組壓縮在一起並同時進行排序。也許這樣的事情?

a = [1, 2, 3, 4, 5] 
b = %w(a b c d e) 

a,b = a.zip(b).sort_by { rand }.transpose 

p a #=> [3, 5, 2, 4, 1] 
p b #=> ["c", "e", "b", "d", "a"] 
+2

+1,'轉置'是一個很好的接觸! –

+0

你的想法看起來不錯,但有沒有辦法做到這一點?請參閱編輯我的問題。 – sawa

3

如何:

ary_a = [ 3, 1, 2] # => [3, 1, 2] 
ary_b = [ 'a', 'b', 'c'] # => ["a", "b", "c"] 
ary_a.zip(ary_b).sort{ |a,b| a.first <=> b.first }.map{ |a,b| b } # => ["b", "c", "a"] 

ary_a.zip(ary_b).sort_by(&:first).map{ |a,b| b } # => ["b", "c", "a"] 
+0

你的想法看起來不錯,但有沒有辦法做到這一點?請參閱編輯我的問題。 – sawa

2

如果條目是獨一無二的,下面可能會工作。我沒有測試過它。這部分複製自https://stackoverflow.com/a/4283318/38765

temporary_copy = a.sort_by{|a_i| some_condition(a_i)} 
new_indexes = a.map {|a_i| temporary_copy.index(a_i)} 

a.each_with_index.sort_by! do |element, i| 
    new_indexes[i] 
end 

b.each_with_index.sort_by! do |element, i| 
    new_indexes[i] 
end 
+0

我在想這樣的事情,但我不認爲Enumerator類具有像map和sort_by這樣的方法的就地修改版本。 –

+0

謝謝。像這樣做是我想要的。我需要看看使用chron/Tin Man的解決方案與'replace'還是你的答案之間的更快。 – sawa