Jay Wang
Jay Wang

Reputation: 37

Ruby exercise regarding Hash

I was working on this Ruby exercise:

Write a function, letter_count(str) that takes a string and returns a hash mapping each letter to its frequency. Do not include spaces.

This is a solution:

def letter_count(str)
  counts = Hash.new(0)
  str.each_char do |char|
    counts[char] += 1 unless char == " "
  end
  counts
end

What does counts[char] += 1 mean? What does char == " " mean?

Upvotes: 2

Views: 150

Answers (3)

Masashi M
Masashi M

Reputation: 2757

What in the world does counts[char] += 1 mean??

a += 1 and a = a + 1 are equivalent. Besides, with counts = Hash.new(0), 0 will be set to the value of a new key(if the key doesn't exit). So, if the char is new, counts[char] become 1 with counts[char] += 1. If it's the second time to see char, counts[char] become 2 with counts[char] += 1 because 1 has been set to counts[char] already.

Alsowhat does char == " " mean?

char == " " returns true if char is " "(space character).

Upvotes: 1

zetetic
zetetic

Reputation: 47548

What in the world does counts[char] += 1 mean??

+= is shorthand for "increment by and assign", i.e. this could be written as:

count = counts[char] # retrieve the value at index "char"
count = count + 1    # add one
counts[char] = count # set the value at index "char" to the new value

Also what does char == " " mean?

== is the equality operator. a == b returns true if a and b have the same value. So char == " " returns true if char is the space character. In this case the equality test is inverted by the trailing unless, so it ends up meaning "add 1 to the count for this character unless the character is a space".

Upvotes: 3

Silvio Mayolo
Silvio Mayolo

Reputation: 70257

In Ruby, += desugars to an = and a +. So counts[char] += 1 becomes counts[char] = counts[char] + 1. Now, normally, if a key does not exist in the hash, the hash access method [] would return nil, which is why we passed 0 into the constructor. Passing a value into the constructor makes that the 'default' return value if a key does not exist. So if counts[char] exists, it adds one to it, and if it doesn't, it initializes it to 0 + 1, which is just 1.

As for the comparison at the end, unless char == " " is a suffix conditional, a Perlism that migrated over into Ruby. In Ruby, you can write conditions at the end of a line, so the following three are equivalent.

# One
if not foo
  bar
end
# Two
bar if not foo
# Three
bar unless foo

The problem description said to exclude spaces, so unless char == " " ensures that the increment operation in the hash will run unless the character is a space.

Upvotes: 2

Related Questions