Ruby数组 - 返回重复和非重复对象的集合

时间:2011-07-30 17:43:33

标签: ruby arrays algorithm logic

我有一组具有以下属性的Race对象:

  • 方式
  • race_period_id
  • track_id

我想收集那些Race对象 - 其中way和track_id属性值相同 - 在一个名为plural_array的新数组中。 (基本上,每个重复的Race对象由way和track_id定义。)在另一个名为singular_array的数组中,我想收集所有那些非重复的Race对象。

例如,假设我有四个具有以下属性值的Race对象:

race1:

  • way = 1
  • race_period_id = 20304
  • track_id = 94949

RACE2:

  • way = 2
  • race_period_id = 20888
  • track_id = 94949

race3

  • way = 1
  • race_period_id = 20899
  • track_id = 94949

race4

  • way = 1
  • race_period_id = 20888
  • track_id = 885858

所以这里我有两个“复数”对象:种族1和种族3。还有两个“奇异”物体:race2和race4。

如果我有一个名为 get_plural_and_singular_arrays(races_array)的方法,我将使用什么算法返回 plural_array (仅包含对象race 1和race3)和 singular_array (仅包含对象race2和race4)?

def get_plural_and_singular_arrays(races_array)
  # algorithm here

  return plural_array, singular_array
end

3 个答案:

答案 0 :(得分: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 :(得分: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>

答案 2 :(得分: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