2013-05-09 62 views
0

我有三個數組。如何基於第三個數組的順序合併Ruby中兩個數組的項目?

我的主列表包含在數據庫驗證不同實體的組合:

ab = ["a:555", "b:222", "a:333", "b:777", "a:777", "a:999", "b:111"] 

我有a兩個陣列和分離b的實體,而是有序的(有些是丟失):

# notice that some of the items from the initial list are missing, but the order is preserved! 
a = [{id}, "a:777", "a:999"] 
b = ["b:222", "b:111"] 

什麼是合併ab的有效方法c保留ab中存在項目的順序?我的程序的預期結果是:

c = ["a:555", "b:222", "a:777", "a:999", "b:111"] 

我是一個紅寶石新手,我想出的一切都是完全醜陋的。


編輯:

我知道它很重要,並會混淆,但ab是複雜的對象(AR)表示在ab的字符串。爲了我的代碼澄清:

ab = ["a:555", "b:222", "a:333", "b:777", "a:777", "a:999", "b:111"] 
a = [{:id => 555}, {:id => 777}, {:id => 999}] 
b = [{:id => 222}, {:id => 111}] 
c = [] 

ab.each { |item| 
parts = item.split(":") 
if parts[0] == "a" 
    if a[0][:id].to_s() == parts[1] 
    c << a.shift() 
    end 
else 
    if b[0][:id].to_s() == parts[1] 
    c << b.shift() 
    end 
end 

} 

puts c 
+2

對不起,我沒有抓住它。你想到了什麼? – oldergod 2013-05-09 09:03:29

+0

是的,問題很混亂。 – 2013-05-09 09:06:09

+0

將在一分鐘內添加我的代碼。 – ddinchev 2013-05-09 09:07:44

回答

3

如果該值的id不是A和B之間的不同,我們可以做到這一點

c = (
    a.map { |e| [ "a:#{e[:id]}", e ] } + 
    b.map { |e| [ "b:#{e[:id]}", e ] } 
). 
sort_by { |e| ab.index(e.first) }. 
map(&:last) 

既然你現在說明他們是不同的,並且有一個方法上產生你的AB鍵的對象,這是簡單的:

c = (a + b).sort_by { |e| ab.index(e.get_ab_string) } 

ab.index是O在AB(N)操作,所以它升級什麼是通常一個NlnN排序,以N^2。爲了使整個溶液放回O(NlnN)運行時,可以預先calaculate AB的索引爲哈希(一個O(N)的操作允許O(1)在sort_by查找):

ab_idx = Hash[ ab.map.with_index { |e,i| [e, i] } ] 
c = (a + b).sort_by { |e| ab_idx(e.get_ab_string) } 
+0

爲什麼需要'Sort_by'? – 2013-05-09 10:53:32

+0

最後一行,真棒。如果可以的話,我會提供兩次。 – ddinchev 2013-05-09 12:07:40

+0

@Priti你的問題讓我困惑。 'sort_by'比你選擇'any?'答案更簡單,更高效。運行sort_by的複雜度爲O(N lnN);你選擇了什麼?是O(N^2) – dbenhur 2013-05-09 14:53:26

0

以下是如何將數組按相同順序排序的基礎。

ary_a = %w[one four three two] 
ary_b = [1, 4, 3, 2] 

將它們合併,排序,然後檢索一個我們想要的分類:有兩個數組開始

ary_a.zip(ary_b).sort_by{ |a, b| b }.map(&:first) 
=> ["one", "two", "three", "four"] 

如果我們想顛倒順序:

ary_a.zip(ary_b).sort_by{ |a, b| -b }.map(&:first) 
=> ["four", "three", "two", "one"] 

或:

​​

如果有三個陣列ys和兩個需要與第三個一起定購:

ary_c = %w[a-one a-four a-three a-two] 
ary_a.zip(ary_c).zip(ary_b).sort_by{ |a, b| b }.map(&:first) 
=> [["one", "a-one"], ["two", "a-two"], ["three", "a-three"], ["four", "a-four"]] 

在合併和排序之前將數組轉換爲所需的形式是問題所在。一旦你有了這些,並且它們有相同數量的元素,這是一個非常簡單的模式。

相關問題