# How to define doubles: Array-to-hash

**URL:** <https://www.ruby-forum.com/t/how-to-define-doubles-array-to-hash/173457>\
**Category:** Ruby\
**Created:** [August 9, 2009, 5:54pm UTC](https://www.ruby-forum.com/t/how-to-define-doubles-array-to-hash/173457 "2009-08-09T17:54:28Z")\
**Posts on this page:** 9\
**Page:** 1

<div class="post-metadata">

**Author:** ![tharrisx](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/t/e19adc/32.png) [@tharrisx](https://www.ruby-forum.com/u/tharrisx)\
**Post date:** [August 9, 2009, 5:54pm UTC](https://www.ruby-forum.com/t/how-to-define-doubles-array-to-hash/173457/1 "2009-08-09T17:54:28Z")

</div>

Hi there,

Assume the following array (contains doubles):

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

What’s the most efficient way to obtain a hash that tells me what  
elements of “original” have more than 1 appearance/entry (= doubles)?

The result should look like this:

result = {“3”=\>4, “4”=\>2}

Thanks for your help!  
Tom-n00b

---

<div class="post-metadata">

**Author:** ![tharrisx](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/t/e19adc/32.png) [@tharrisx](https://www.ruby-forum.com/u/tharrisx)\
**Post date:** [August 9, 2009, 6:11pm UTC](https://www.ruby-forum.com/t/how-to-define-doubles-array-to-hash/173457/2 "2009-08-09T18:11:09Z")

</div>

Tom Ha wrote:

> result = {“3”=\>4, “4”=\>2}
> 
> Thanks for your help!  
> Tom-n00b

I won’t argue that it’s the most “efficient” but the following both  
works and is easy to understand.

irb(main):007:0\> original.each do |o|  
irb(main):008:1\* o = o.to\_s  
irb(main):009:1\> result[o] ||= 0  
irb(main):010:1\> result[o] += 1  
irb(main):011:1\> end  
=\> [1, 2, 3, 3, 3, 3, 4, 4, 5]  
irb(main):012:0\> result  
=\> {“1”=\>1, “2”=\>1, “3”=\>4, “4”=\>2, “5”=\>1}  
irb(main):013:0\> result.delete\_if {|k, v| v == 1}  
=\> {“3”=\>4, “4”=\>2}

---

<div class="post-metadata">

**Author:** ![tharrisx](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/t/e19adc/32.png) [@tharrisx](https://www.ruby-forum.com/u/tharrisx)\
**Post date:** [August 9, 2009, 7:18pm UTC](https://www.ruby-forum.com/t/how-to-define-doubles-array-to-hash/173457/3 "2009-08-09T19:18:29Z")

</div>

Hi,

Am Montag, 10. Aug 2009, 00:54:31 +0900 schrieb Tom Ha:

> original = [1, 2, 3, 3, 3, 3, 4, 4, 5]
> 
> The result should look like this:
> 
> result = {“3”=\>4, “4”=\>2}

Here are two:

original.inject({}) { |h,e| h[e] ||= 0 ; h[e] += 1 ; h }

and

h = Hash.new { |h,k| h[k] = 0 }  
original.each { |e| h[e] += 1 }  
h

then

h.reject! { |k,v| k == 1 }

Bertram

---

<div class="post-metadata">

**Author:** ![tharrisx](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/t/e19adc/32.png) [@tharrisx](https://www.ruby-forum.com/u/tharrisx)\
**Post date:** [August 9, 2009, 7:48pm UTC](https://www.ruby-forum.com/t/how-to-define-doubles-array-to-hash/173457/4 "2009-08-09T19:48:45Z")

</div>

Great!

Thanks a lot, guys!

---

<div class="post-metadata">

**Author:** ![tharrisx](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/t/e19adc/32.png) [@tharrisx](https://www.ruby-forum.com/u/tharrisx)\
**Post date:** [August 10, 2009, 1:17am UTC](https://www.ruby-forum.com/t/how-to-define-doubles-array-to-hash/173457/5 "2009-08-10T01:17:33Z")

</div>

Bertram S. wrote:

> Here are two:
> 
> original.inject({}) { |h,e| h[e] ||= 0 ; h[e] += 1 ; h }
> 
> and
> 
> h = Hash.new { |h,k| h[k] = 0 }  
> original.each { |e| h[e] += 1 }  
> h
> 
> then
> 
> h.reject! { |k,v| k == 1 }
> 
> Bertram

Your code doesn’t produce the desired result, the op wanted an efficient  
solution, and this:

h = Hash.new { |h,k| h[k] = 0 }

is equivalent to:

h = Hash.new(0)

How about a regex?

original = [1, 2, 3, 3, 3, 3, 4, 4, 5]  
results = {}

str = original.to\_s

str.scan(/((\d)\2+)/).each do |match|  
results[match[1]] = match[0].length  
end

p results

–output:–  
{“3”=\>4, “4”=\>2}

…but that is no faster than:

results = Hash.new(0)

original.each do |elmt|  
results[elmt.to\_s] += 1  
end

results.delete\_if {|key, val| val == 1}

p results

–output:–  
{“3”=\>4, “4”=\>2}

---

<div class="post-metadata">

**Author:** ![tharrisx](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/t/e19adc/32.png) [@tharrisx](https://www.ruby-forum.com/u/tharrisx)\
**Post date:** [August 10, 2009, 8:33am UTC](https://www.ruby-forum.com/t/how-to-define-doubles-array-to-hash/173457/6 "2009-08-10T08:33:19Z")

</div>

Hi –

On Mon, 10 Aug 2009, Bertram S. wrote:

> > h = Hash.new(0)
> 
> Arrgh. Of course.

Actually they’re not equivalent.

> > h = Hash.new(0)  
> > =\> {}
> 
> > h[1]  
> > =\> 0
> 
> > h  
> > =\> {}
> 
> > h = Hash.new {|h,k| h[k] = 0 }  
> > =\> {}
> 
> > h[1]  
> > =\> 0
> 
> > h  
> > =\> {1=\>0}

David

---

<div class="post-metadata">

**Author:** ![tharrisx](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/t/e19adc/32.png) [@tharrisx](https://www.ruby-forum.com/u/tharrisx)\
**Post date:** [August 10, 2009, 1:44am UTC](https://www.ruby-forum.com/t/how-to-define-doubles-array-to-hash/173457/7 "2009-08-10T01:44:46Z")

</div>

Hi,

Am Montag, 10. Aug 2009, 08:17:42 +0900 schrieb 7stud --:

> Bertram S. wrote:
> 
> > h = Hash.new { |h,k| h[k] = 0 }
> 
> h = Hash.new { |h,k| h[k] = 0 }
> 
> is equivalent to:
> 
> h = Hash.new(0)

Arrgh. Of course.

Bertram

---

<div class="post-metadata">

**Author:** ![tharrisx](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/t/e19adc/32.png) [@tharrisx](https://www.ruby-forum.com/u/tharrisx)\
**Post date:** [August 10, 2009, 10:27am UTC](https://www.ruby-forum.com/t/how-to-define-doubles-array-to-hash/173457/8 "2009-08-10T10:27:27Z")

</div>

Hi,

Am Montag, 10. Aug 2009, 15:32:44 +0900 schrieb David A. Black:

> > > h = Hash.new(0)  
> > > =\> {}
> > 
> > > h = Hash.new {|h,k| h[k] = 0 }  
> > > =\> {}
> > 
> > > h[1]  
> > > =\> 0
> > 
> > > h  
> > > =\> {1=\>0}

Arrgh. Of course.

I remind that my code called Hash#[] just in

h[e] += 1

and therefore it is even more efficient to use the default value  
solution.

Bertram

---

<div class="post-metadata">

**Author:** ![tharrisx](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/t/e19adc/32.png) [@tharrisx](https://www.ruby-forum.com/u/tharrisx)\
**Post date:** [August 11, 2009, 4:13pm UTC](https://www.ruby-forum.com/t/how-to-define-doubles-array-to-hash/173457/9 "2009-08-11T16:13:28Z")

</div>

On Mon, Aug 10, 2009 at 1:17 AM, 7stud –[removed\_email\_address@domain.invalid](mailto:removed_email_address@domain.invalid) wrote:

> Your code doesn’t produce the desired result, the op wanted an efficient  
> solution, and this:

Actually, he wanted the “most efficient”.

This is faster than the inject/hash method:

```
result = []
lastv = nil
count = 1
original.sort.each do |v|
  if v == lastv
    count += 1
  else
    result.push(lastv, count) if lastv
    count = 1
    lastv = v
  end
end
result.push(lastv, count)
hash = Hash[*result]

```

This is O(n logn+n) while the inject method should be theoretically be  
O(n) (assuming that Hash tables lookups/insertions are constant-time  
and inject is linear). However, its significantly faster (250%) on  
1.8.6-mswin32 and a little faster (50%) on 1.9.1-mingw32, even on  
large arrays (millions of elements). Anyone who can explain why?
