34

你如何计算红宝石数组中的重复项?

例如,如果我的数组有三个 a,我怎么能数呢

4

17 回答 17

56

另一个版本的哈希,数组中的每个元素都有一个键,每个元素的计数值

a = [ 1, 2, 3, 3, 4, 3]
h = Hash.new(0)
a.each { | v | h.store(v, h[v]+1) }

# h = { 3=>3, 2=>1, 1=>1, 4=>1 } 
于 2009-11-19T19:12:41.363 回答
37

鉴于:

arr = [ 1, 2, 3, 2, 4, 5, 3]

我最喜欢的计算元素的方法是:

counts = arr.group_by{|i| i}.map{|k,v| [k, v.count] }

# => [[1, 1], [2, 2], [3, 2], [4, 1], [5, 1]]

如果您需要哈希而不是数组:

Hash[*counts.flatten]

# => {1=>1, 2=>2, 3=>2, 4=>1, 5=>1}
于 2012-11-22T20:30:26.060 回答
26

这将产生重复元素作为散列,其中包含每个重复项的出现次数。让代码说话:

#!/usr/bin/env ruby

class Array
  # monkey-patched version
  def dup_hash
    inject(Hash.new(0)) { |h,e| h[e] += 1; h }.select { 
      |k,v| v > 1 }.inject({}) { |r, e| r[e.first] = e.last; r }
  end
end

# unmonkeey'd
def dup_hash(ary)
  ary.inject(Hash.new(0)) { |h,e| h[e] += 1; h }.select { 
    |_k,v| v > 1 }.inject({}) { |r, e| r[e.first] = e.last; r }
end

p dup_hash([1, 2, "a", "a", 4, "a", 2, 1])
# {"a"=>3, 1=>2, 2=>2}

p [1, 2, "Thanks", "You're welcome", "Thanks", 
  "You're welcome", "Thanks", "You're welcome"].dup_hash
# {"You're welcome"=>3, "Thanks"=>3}
于 2009-11-19T18:17:49.260 回答
14

简单的。

arr = [2,3,4,3,2,67,2]
repeats = arr.length - arr.uniq.length
puts repeats
于 2009-11-19T18:38:50.667 回答
13
arr = %w( a b c d c b a )
# => ["a", "b", "c", "d", "c", "b", "a"]

arr.count('a')
# => 2
于 2013-04-27T23:53:46.230 回答
11

另一种计算数组重复的方法是:

arr= [2,2,3,3,2,4,2]

arr.group_by{|x| x}.map{|k,v| [k,v.count] }

结果是

[[2, 4], [3, 2], [4, 1]]

于 2015-05-06T07:38:28.867 回答
7

需要 1.8.7+group_by

ary = %w{a b c d a e f g a h i b}
ary.group_by{|elem| elem}.select{|key,val| val.length > 1}.map{|key,val| key}
# => ["a", "b"]

使用 1.9+ 这可以稍微简化,因为 Hash#select 将返回一个哈希。

ary.group_by{|elem| elem}.select{|key,val| val.length > 1}.keys
# => ["a", "b"]
于 2009-11-19T18:42:06.183 回答
4

要计算单个元素的实例,请使用注入

array.inject(0){|count,elem| elem == value ? count+1 : count}
于 2009-12-15T21:00:07.317 回答
4
arr = [1, 2, "a", "a", 4, "a", 2, 1]

arr.group_by(&:itself).transform_values(&:size)
#=> {1=>2, 2=>2, "a"=>3, 4=>1}
于 2020-03-11T14:52:31.643 回答
2

我认为没有内置方法。如果您只需要重复的总数,则可以采用 a.length - a.uniq.length。如果您正在寻找单个特定元素的计数,请尝试
a.select {|e| e == my_element}.length.

于 2009-11-19T18:19:01.270 回答
2

grep 呢?

arr = [1, 2, "Thanks", "You're welcome", "Thanks", "You're welcome", "Thanks", "You're welcome"]

arr.grep('Thanks').size # => 3
于 2013-03-14T19:58:55.427 回答
2

这简单:

words = ["aa","bb","cc","bb","bb","cc"]

一行简单的解决方案是:

words.each_with_object(Hash.new(0)) { |word,counts| counts[word] += 1 }

这个对我有用。

谢谢!!

于 2014-05-28T11:31:57.247 回答
2

改进@Kim的回答:

arr = [1, 2, "a", "a", 4, "a", 2, 1]
Hash.new(0).tap { |h| arr.each { |v| h[v] += 1 } }
# => {1=>2, 2=>2, "a"=>3, 4=>1}
于 2016-01-27T22:02:09.990 回答
2

Ruby >= 2.7解决方案:

添加了一种新方法.tally

统计集合,即计算每个元素的出现次数。返回一个散列,其中集合的元素作为键,相应的计数作为值。

所以现在,您将能够:

["a", "b", "c", "b"].tally  #=> {"a"=>1, "b"=>2, "c"=>1}
于 2021-03-14T09:33:49.147 回答
1

获取数组中重复元素的 Ruby 代码:

numbers = [1,2,3,1,2,0,8,9,0,1,2,3]
similar =  numbers.each_with_object([]) do |n, dups|
    dups << n if seen.include?(n)
    seen << n 
end
print "similar --> ", similar
于 2018-11-06T09:49:25.133 回答
1

另一种方法是使用each_with_object

a = [ 1, 2, 3, 3, 4, 3]

hash = a.each_with_object({}) {|v, h|
  h[v] ||= 0
  h[v] += 1
}

# hash = { 3=>3, 2=>1, 1=>1, 4=>1 } 

这样,调用不存在的键,例如hash[5]将返回nil而不是0使用Kim 的解决方案

于 2019-03-22T21:06:03.470 回答
0

我过去曾使用过reduce/ inject,如下所示

array = [1,5,4,3,1,5,6,8,8,8,9]
array.reduce (Hash.new(0)) {|counts, el| counts[el]+=1; counts}

生产

=> {1=>2, 5=>2, 4=>1, 3=>1, 6=>1, 8=>3, 9=>1}
于 2016-11-02T06:17:58.377 回答