计算数组中的重复项

时间:2013-11-27 11:52:27

标签: ruby arrays duplicates

sold = Array.new

ticketfile.each {|line| 
    a = line.split(",")

    nr2 = Ticket.new(a[0],a[1])
    sold<<nr2

}

这是我的数组,我有以下元素:ticknum和serialnum。 它从文本文件中获取这些信息。

我想要的是找到所有重复项(其中ticknum和serialnum是相同的)并创建一个新的数组,其中ticknum,serialnum和重复数量。

有人可以帮我解决这个问题吗?

2 个答案:

答案 0 :(得分:1)

我会使用Enumerable#group_by

模仿您的Ticket class

class Ticket < Struct.new(:ticknum, :serialnum); end
=> nil

创建一些门票:

(这只是将您的文件模拟为Array

tickets = [Ticket.new(1, 2), Ticket.new(1, 2), Ticket.new(1, 3), Ticket.new(1, 4), Ticket.new(1, 4)]
=> [#<struct Ticket ticknum=1, serialnum=2>,
 #<struct Ticket ticknum=1, serialnum=2>,
 #<struct Ticket ticknum=1, serialnum=3>,
 #<struct Ticket ticknum=1, serialnum=4>,
 #<struct Ticket ticknum=1, serialnum=4>]

这是一个group_by

groups = tickets.group_by { |t| [t.ticknum, t.serialnum] }
=> {[1, 2]=>
  [#<struct Ticket ticknum=1, serialnum=2>,
   #<struct Ticket ticknum=1, serialnum=2>],
 [1, 3]=>[#<struct Ticket ticknum=1, serialnum=3>],
 [1, 4]=>
  [#<struct Ticket ticknum=1, serialnum=4>,
   #<struct Ticket ticknum=1, serialnum=4>]}

过滤掉非重复项:

duplicates = groups.reject { |k, v| v.length < 2 }
=> {[1, 2]=>
  [#<struct Ticket ticknum=1, serialnum=2>,
   #<struct Ticket ticknum=1, serialnum=2>],
 [1, 4]=>
  [#<struct Ticket ticknum=1, serialnum=4>,
   #<struct Ticket ticknum=1, serialnum=4>]}

列出每个重复Ticket出现的次数:

duplicates.values.each do | group |
  puts "There are #{group.length} of #{group.first}"
end  
There are 2 of #<struct Ticket ticknum=1, serialnum=2>
There are 2 of #<struct Ticket ticknum=1, serialnum=4>

答案 1 :(得分:0)

我建议使用非常简单的解决方案:

ticketfile.each_with_object(Hash.new(0)) {|line, hash| 
  hash[line.split(",")] += 1
}

您可以在eql?类上定义Ticket方法,将其用作哈希键(请参阅Which equality test does Ruby's Hash use when comparing keys?