One of the most used features in any programming language is a Hash . Today we are going to talk about some of the Ruby’s Hash features, which are well documented, but rarely used — parameters of the Hash constructor. In the second part of this article we will take a look at the arguments of the Array class’ constructor.

Take a look at the following example.

1

2

3

4

5

6

a = % w ( apple banana apple )

h = a. inject ( { } ) do | h, fruit |

h [ fruit ] || = 0

h [ fruit ] + = 1

h

end

Here we have an array of fruits and we need to calculate a frequency of each fruit. As you can see, in the line 3 we are initializing frequency value to 0 if there are was no fruit with this name before. We can simplify this code:

1

2

3

4

5

a = % w ( apple banana apple )

h = a. inject ( Hash . new ( 0 ) ) do | h, fruit |

h [ fruit ] + = 1

h

end

In line 2 we are creating a new hash, which default value is 0 . This means that if we would try to retrieve value for a non-existing key, 0 would be returned.

Let’s check another example:

1

2

3

4

5

6

a = % w ( apple banana apple )

h = { }

a. each_with_index do | fruit, i |

h [ fruit ] || = [ ]

h [ fruit ] << i

end

Here we are collecting indexes of each fruit in the source array. But now we can’t just create a new hash and pass [] as the default value, because all keys in this hash will refer to the same array, so in result we will get an array [1, 2, 3] for each fruit. So let’s try the following:

1

2

3

4

5

a = % w ( apple banana apple )

h = Hash . new { | h, key | h [ key ] = [ ] }

a. each_with_index do | fruit, i |

h [ fruit ] << i

end

In this case we are creating a new array object for any non-existing key, that was accessed. So

1

h [ 'some non-existing key' ]

will return [] and save it in the hash. When you will hit this key next time, previously created array will be returned.

You can pass a block to Array constructor too. For example, you need an array with 10 random numbers:

1

2

a = [ ]

10 . times { a << rand ( 100 ) }

You can simplify it using map method:

1

a = ( 1 .. 10 ) . map { rand ( 100 ) }

But you can do it even easier:

1

a = Array . new ( 10 ) { rand ( 100 ) }

Next Memo will cover managing Ruby Gems, so stay tuned.