2011-07-30 60 views
1

我有比賽的對象具有以下屬性的數組:紅寶石陣列 - 返回重複的和非重複的對象的集合

  • 方式
  • race_period_id
  • track_id

我想要在名爲plural_array的新數組中收集這些Race對象 - 其中way和track_id屬性值相同 - 。 (基本上,每個重複的Race對象由way和track_id定義。)在另一個名爲singular_array的數組中,我想收集所有那些非重複的Race對象。

例如,讓我們假設我有以下屬性值的四個賽對象:

race1:

  • 方式= 1
  • race_period_id = 20304
  • track_id = 94949

race2:

  • 方式= 2
  • race_period_id = 20888
  • track_id = 94949

race3

  • 方式= 1
  • race_period_id = 20899
  • track_id = 94949

race4

  • 方式= 1
  • race_period_id = 20888
  • track_id = 885858

所以在這裏我有兩個 「複數」 的對象:1賽和race3。還有兩個「奇異」的對象:race2和race4。

如果我有一個名爲方法get_plural_and_singular_arrays(races_array),我會用什麼算法返回plural_array(含對象只種1和race3)和singular_array(只包含對象RACE2和race4) ?

def get_plural_and_singular_arrays(races_array) 
    # algorithm here 

    return plural_array, singular_array 
end 

回答

2

您可以通過使用group_by,然後的,結果組織成單打和雙打開始:

list.group_by do |i| 
    [ i.way, i.track_id ] 
end.values.group_by do |list| 
    list.length > 1 
end 

您應該具備的關鍵truefalse爲您的多個條目和單條目的哈希分別。

+1

+1一個漂亮實用的解決方案。但我會使用分區:list.group_by {| r | [r.way,r.track_id]} .partition {| ary | ary.size> 1} – tokland

+0

+1對於可以寫成單行的代碼! –

+0

順便提一下,我的單行程(使用'ActiveSupport'數組增強功能):'list.group_by {| i | [i.way,i.track_id]} .partition(&:many?)' –

0

代碼:

def get_plural_and_singular_arrays(races_array) 
    singular_array, plural_array = [], [] 
    # algorithm here 
    races_array.group_by { |race| [race.way, race.track_id] }.each do |key, values| 
    if values.size == 1 
     singular_array << values[0] 
    else 
     plural_array += values 
    end 
    end 
    return plural_array, singular_array 
end 

測試:

irb(main):025:0> Race = Struct.new(:way, :track_id) 
=> Race 
irb(main):026:0> r1 = Race.new(1, 2) 
=> #<struct Race way=1, track_id=2> 
irb(main):027:0> r2 = Race.new(1, 2) 
=> #<struct Race way=1, track_id=2> 
irb(main):028:0> r3 = Race.new(3, 4) 
=> #<struct Race way=3, track_id=4> 
irb(main):029:0> r4 = Race.new(3, 5) 
=> #<struct Race way=3, track_id=5> 
irb(main):030:0> get_plural_and_singular_arrays([r1, r2, r3, r4]) 
=> [[#<struct Race way=1, track_id=2>, #<struct Race way=1, track_id=2>], [#<str 
uct Race way=3, track_id=4>, #<struct Race way=3, track_id=5>]] 
irb(main):031:0> 
0

這可能會實現:

def get_plural_and_singular(races) 
    grouped_races = races.group_by { |r| [r.way, r.track_id] }.values 
    grouped_races.partition { |grp| grp.size > 1 }.map(&:flatten) 
end