# Find that number is repeated more and less times in an array

**URL:** <https://rubytalk.org/t/find-that-number-is-repeated-more-and-less-times-in-an-array/65854>\
**Category:** ruby-talk\
**Created:** [8 July 2012 00:32 UTC](https://rubytalk.org/t/find-that-number-is-repeated-more-and-less-times-in-an-array/65854 "2012-07-08T00:32:39Z")\
**Posts on this page:** 8\
**Page:** 1

<div class="post-metadata">

**Author:** ![7stud2](https://avatars.discourse-cdn.com/v4/letter/7/9de053/32.png) [@7stud2](https://rubytalk.org/u/7stud2)\
**Post date:** [8 July 2012 00:32 UTC](https://rubytalk.org/t/find-that-number-is-repeated-more-and-less-times-in-an-array/65854/1 "2012-07-08T00:32:39Z")

</div>

Hi all.

I'm trying to find a function to find the number that is repeated over  
and the least is repeated within an array. I tried a lot of things but I  
can not make it work.

For example:

a = [1 2 2 3 5 4 6 2 6 5 4]

I calculate the number that is repeated over and less repeats and if  
possible to calculate something like this for example:

=\> With 0 repeats found the number 1.3, etc.  
=\> With 1 repetition was found the number: 4, etc.  
=\> With 2 repetitions was found the number 5, etc.

Thanks.

> **···**
>
> --  
> Posted via [http://www.ruby-forum.com/](http://www.ruby-forum.com/).

---

<div class="post-metadata">

**Author:** ![7stud2](https://avatars.discourse-cdn.com/v4/letter/7/9de053/32.png) [@7stud2](https://rubytalk.org/u/7stud2)\
**Post date:** [8 July 2012 01:20 UTC](https://rubytalk.org/t/find-that-number-is-repeated-more-and-less-times-in-an-array/65854/2 "2012-07-08T01:20:11Z")

</div>

Hi,

I don't understand what you're saying.

OK, you have a given number n. Are you looking for all elements that  
occur \*at least\* n times in the array?

To count the number of occurences, you can use Enumerable#inject:

array = [1, 2, 2, 3, 2, 5]  
element = 2  
element\_count = array.inject 0 do |count, x|  
&nbsp;&nbsp;count + (x == element ? 1 : 0)  
end

Or a more lowlevel solution:

array = [1, 2, 2, 3, 2, 5]  
element = 2  
element\_count = 0  
array.each do |x|  
&nbsp;&nbsp;element\_count += 1 if x == element  
end

> **···**
>
> --  
> Posted via [http://www.ruby-forum.com/](http://www.ruby-forum.com/).

---

<div class="post-metadata">

**Author:** ![botp1](https://avatars.discourse-cdn.com/v4/letter/b/6de8d8/32.png) [@botp1](https://rubytalk.org/u/botp1)\
**Post date:** [8 July 2012 02:49 UTC](https://rubytalk.org/t/find-that-number-is-repeated-more-and-less-times-in-an-array/65854/3 "2012-07-08T02:49:22Z")

</div>

> =\> With 0 repeats found the number 1.3, etc.  
> =\> With 1 repetition was found the number: 4, etc.  
> =\> With 2 repetitions was found the number 5, etc.

fire up irb or pry, and play w ruby,  
eg,

> a. group\_by{|x|x}.group\_by{|x,y| y.size-1}.each\_with\_object({}){|(k,v),h| h[k] = v.flatten.uniq}

=\> {0=\>[1, 3], 2=\>[2], 1=\>[5, 4, 6]}

> **···**
>
> On Sun, Jul 8, 2012 at 8:32 AM, Joao Silva \<lists@ruby-forum.com\> wrote:

---

<div class="post-metadata">

**Author:** ![7stud2](https://avatars.discourse-cdn.com/v4/letter/7/9de053/32.png) [@7stud2](https://rubytalk.org/u/7stud2)\
**Post date:** [8 July 2012 06:43 UTC](https://rubytalk.org/t/find-that-number-is-repeated-more-and-less-times-in-an-array/65854/4 "2012-07-08T06:43:39Z")

</div>

Hash[a.group\_by{|x|a.count(x)-1}.map{|k,v|[k,v.uniq]}]  
=\>{0=\>[1, 3], 2=\>[2], 1=\>[5, 4, 6]}

or  
a.group\_by{|x|a.count(x)-1}.each\_with\_object({}){|(k,v),h|h[k]=v.uniq}  
=\>{0=\>[1, 3], 2=\>[2], 1=\>[5, 4, 6]}

Benchmark testing:

[Benchmark.bm](http://Benchmark.bm) do |x|  
x.report { n.times {  
&nbsp;&nbsp;a.group\_by{|x|x}.group\_by{|x,y|  
y.size-1}.each\_with\_object({}){|(k,v),h|  
&nbsp;&nbsp;&nbsp;&nbsp;h[k] =v.flatten.uniq  
&nbsp;&nbsp;}  
}}  
x.report { n.times {  
&nbsp;&nbsp;Hash[a.group\_by{|x|a.count(x)-1}.map{|k,v|[k,v.uniq]}]  
}}  
x.report { n.times {  
&nbsp;&nbsp;a.group\_by{|x|a.count(x)-1}.each\_with\_object({}){|(k,v),h|h[k]=v.uniq}  
}}  
end

n = 50000  
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;user system total real  
&nbsp;&nbsp;&nbsp;0.920000 0.000000 0.920000 ( 0.943945)  
&nbsp;&nbsp;&nbsp;0.730000 0.000000 0.730000 ( 0.732669)  
&nbsp;&nbsp;&nbsp;0.740000 0.000000 0.740000 ( 0.742029)

n = 500000  
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;user system total real  
&nbsp;&nbsp;&nbsp;9.040000 0.000000 9.040000 ( 9.062923)  
&nbsp;&nbsp;&nbsp;7.330000 0.000000 7.330000 ( 7.382192)  
&nbsp;&nbsp;&nbsp;7.070000 0.000000 7.070000 ( 7.085146)

> **···**
>
> --  
> Posted via [http://www.ruby-forum.com/](http://www.ruby-forum.com/).

---

<div class="post-metadata">

**Author:** ![7stud2](https://avatars.discourse-cdn.com/v4/letter/7/9de053/32.png) [@7stud2](https://rubytalk.org/u/7stud2)\
**Post date:** [8 July 2012 15:23 UTC](https://rubytalk.org/t/find-that-number-is-repeated-more-and-less-times-in-an-array/65854/5 "2012-07-08T15:23:27Z")

</div>

Joao Silva wrote in post #1067849:

> a = [1 2 2 3 5 4 6 2 6 5 4]
> 
> I calculate the number that is repeated over and less repeats and if  
> possible to calculate something like this for example:
> 
> =\> With 0 repeats found the number 1.3, etc.  
> =\> With 1 repetition was found the number: 4, etc.  
> =\> With 2 repetitions was found the number 5, etc.

Do it in steps. First count the number of times each value is seen:

a = [1, 2, 2, 3, 5, 4, 6, 2, 6, 5, 4]  
counts = Hash.new(0)  
a.each { |val| counts[val] += 1 }  
# optional: counts = counts.sort\_by { |val,count| count }  
counts.each do |val,count|  
&nbsp;&nbsp;puts "With #{count-1} repeats found the number #{val}"  
end

This is a starting point. Then you can look at grouping together values  
with the same count.

a = [1, 2, 2, 3, 5, 4, 6, 2, 6, 5, 4]  
counts = Hash.new(0)  
a.each { |val| counts[val] += 1 }  
groups = {}  
counts.each do |val,count|  
&nbsp;&nbsp;groups[count] ||=   
&nbsp;&nbsp;groups[count] \<\< val  
end  
groups.each do |count,vals|  
&nbsp;&nbsp;puts "With #{count-1} repeats found #{vals.sort.join(", ")}"  
end

When you're clear what's happening here then you can look at the more  
compact versions using group\_by.

> **···**
>
> --  
> Posted via [http://www.ruby-forum.com/\](http://www.ruby-forum.com/%5C).

---

<div class="post-metadata">

**Author:** ![7stud2](https://avatars.discourse-cdn.com/v4/letter/7/9de053/32.png) [@7stud2](https://rubytalk.org/u/7stud2)\
**Post date:** [8 July 2012 20:13 UTC](https://rubytalk.org/t/find-that-number-is-repeated-more-and-less-times-in-an-array/65854/6 "2012-07-08T20:13:08Z")

</div>

Brian Candler wrote in post #1067902:

> a = [1, 2, 2, 3, 5, 4, 6, 2, 6, 5, 4]  
> counts = Hash.new(0)  
> a.each { |val| counts[val] += 1 }  
> groups = {}  
> counts.each do |val,count|  
> &nbsp;&nbsp;groups[count] ||=   
> &nbsp;&nbsp;groups[count] \<\< val  
> end  
> groups.each do |count,vals|  
> &nbsp;&nbsp;puts "With #{count-1} repeats found #{vals.sort.join(", ")}"  
> end

One last thing, how do I print the results that I stay in order, because  
the above code prints:

With 0 repeats found 1, 3  
With 2 repeats found 2  
With 1 repeats found 4, 5, 6

and I seek it to print in order:

With 0 repeats found 1, 3  
With 1 repeats found 4, 5, 6  
With 2 repeats found 2

> **···**
>
> --  
> Posted via [http://www.ruby-forum.com/\](http://www.ruby-forum.com/%5C).

---

<div class="post-metadata">

**Author:** ![Jesus\_Gabriel\_y\_Gala](https://avatars.discourse-cdn.com/v4/letter/j/96bed5/32.png) [@Jesus\_Gabriel\_y\_Gala](https://rubytalk.org/u/Jesus_Gabriel_y_Gala)\
**Post date:** [9 July 2012 07:14 UTC](https://rubytalk.org/t/find-that-number-is-repeated-more-and-less-times-in-an-array/65854/7 "2012-07-09T07:14:47Z")

</div>

> Brian Candler wrote in post #1067902:
> 
> > a = [1, 2, 2, 3, 5, 4, 6, 2, 6, 5, 4]  
> > counts = Hash.new(0)  
> > a.each { |val| counts[val] += 1 }  
> > groups = {}  
> > counts.each do |val,count|  
> > &nbsp;&nbsp;groups[count] ||=   
> > &nbsp;&nbsp;groups[count] \<\< val  
> > end  
> > groups.each do |count,vals|  
> > &nbsp;&nbsp;puts "With #{count-1} repeats found #{vals.sort.join(", ")}"  
> > end
> 
> One last thing, how do I print the results that I stay in order, because  
> the above code prints:
> 
> With 0 repeats found 1, 3  
> With 2 repeats found 2  
> With 1 repeats found 4, 5, 6
> 
> and I seek it to print in order:

groups.sort.each do |count,vals|  
&nbsp;&nbsp;puts "With #{count-1} repeats found #{vals.sort.join(", ")}"  
end

> With 0 repeats found 1, 3  
> With 1 repeats found 4, 5, 6  
> With 2 repeats found 2

I think you should read a little bit about classes Array, Hash and  
module Enumerable, and try yourself things around in IRB until you  
feel more comfortable about how to use many of the facilities they  
provide.

Jesus.

> **···**
>
> On Sun, Jul 8, 2012 at 10:13 PM, Joao Silva \<lists@ruby-forum.com\> wrote:

---

<div class="post-metadata">

**Author:** ![Robert\_K1](https://yyz1.discourse-cdn.com/flex029/user_avatar/rubytalk.org/robert_k1/32/1830_2.png) [@Robert\_K1](https://rubytalk.org/u/Robert_K1)\
**Post date:** [9 July 2012 09:58 UTC](https://rubytalk.org/t/find-that-number-is-repeated-more-and-less-times-in-an-array/65854/8 "2012-07-09T09:58:09Z")

</div>

Alternative solution

irb(main):001:0\> a = [1, 2, 2, 3, 5, 4, 6, 2, 6, 5, 4]  
=\> [1, 2, 2, 3, 5, 4, 6, 2, 6, 5, 4]  
irb(main):002:0\> max=0; counts = a.inject(Hash.new(0)) {|c, x|  
cc=(c+=1); max=cc if cc\>max; c}  
=\> {1=\>1, 2=\>3, 3=\>1, 5=\>2, 4=\>2, 6=\>2}  
irb(main):003:0\> 1.upto(max){|r| printf "With %d repeats: %p\n", r,  
counts.select {|k,v| v==r}.map{|k,v|k} }  
With 1 repeats: [1, 3]  
With 2 repeats: [5, 4, 6]  
With 3 repeats: [2]  
=\> 1

(Explanation omitted for pedagogical reasons.)

Have fun!

robert

> **···**
>
> On Mon, Jul 9, 2012 at 9:14 AM, Jesús Gabriel y Galán \<jgabrielygalan@gmail.com\> wrote:
> 
> > On Sun, Jul 8, 2012 at 10:13 PM, Joao Silva \<lists@ruby-forum.com\> wrote:
> > 
> > > Brian Candler wrote in post #1067902:
> > > 
> > > > a = [1, 2, 2, 3, 5, 4, 6, 2, 6, 5, 4]  
> > > > counts = Hash.new(0)  
> > > > a.each { |val| counts[val] += 1 }  
> > > > groups = {}  
> > > > counts.each do |val,count|  
> > > > &nbsp;&nbsp;groups[count] ||=   
> > > > &nbsp;&nbsp;groups[count] \<\< val  
> > > > end  
> > > > groups.each do |count,vals|  
> > > > &nbsp;&nbsp;puts "With #{count-1} repeats found #{vals.sort.join(", ")}"  
> > > > end
> > > 
> > > One last thing, how do I print the results that I stay in order, because  
> > > the above code prints:
> > > 
> > > With 0 repeats found 1, 3  
> > > With 2 repeats found 2  
> > > With 1 repeats found 4, 5, 6
> > > 
> > > and I seek it to print in order:
> > 
> > groups.sort.each do |count,vals|  
> > &nbsp;&nbsp;puts "With #{count-1} repeats found #{vals.sort.join(", ")}"  
> > end
> 
> --  
> remember.guy do |as, often| as.you\_can - without end  
> [http://blog.rubybestpractices.com/](http://blog.rubybestpractices.com/)
