Reputation: 25
I'm new to coding and have only been doing this for about 12 days so forgive my n00biness. I decided to learn Ruby first as it's not particularly hard to get the hang of. I'm making a small program that tracks and stores information from users. In this particular section of the code I want to track and store how the user rated a particular movie. I've been playing around with a few features such as adding, displaying, deleting and updating the movies (these four elements are the "whens" as part of a case statement). I have hit a roadblock on the displaying part.
The hash, in question, I've been using to test the program is (Disclaimer: movie ratings were not intended to offend):
movies = {
The_Dark_Knight: 10,
Justice_League: 1,
Wolverine_Origins: 7,
Wonder_Woman: 6,
Man_of_Steel: 8
}
and I want Ruby to display the title of the movies in the hash (after iterating through them) alongside the ratings as such:
=begin
The Dark Knight: 10
Justice League: 1
Wolverine Origins: 7
Wonder Woman: 6
Man of Steel: 8
=end
This is the display part of the case statement. 'When' the user selects display it should show them the titles of the movie alongside the rating as shown above.
when "display"
movies.each {|title, rating|
title_as_string = title.to_s.split('_').map(&:capitalize).join(' ')
puts "#{title_as_string}: #{rating}"
}
This is the way I went about it and believe me when I tell you it took me very long to figure that out. It got me the result I wanted but...
...The question is: Is there a more concise or better way to do this? If so, how?
Answers will be very much appreciated.
Upvotes: 0
Views: 231
Reputation: 26778
There are many ways to do the same thing.
You can use String#gsub
- this stands for "global substitution" which is exactly what you want to do - substitute _
for a space:
title_as_string = title.to_s.gsub("_", " ")
You could also use String#tr
- the method doesn't do the exact same thing but in this case you could replace gsub
with tr
and it would have the same result
Use strings as keys. It's not as easy to write it out because you need to use hashrocket (=>
) syntax but removes the whole need for the substitution:
movies = {
"The Dark Knight" => 10,
"Justice League" => 1,
# etc
}
Put spaces in your symbols - this approach isn't as commonly used but it is totally valid syntax:
movies = {
"The Dark Knight": 10,
"Justice League": 1,
# etc
}
The only One difference between this and string keys is I have replaced the hashrocket =>
with colon :
. You still need to call .to_s
in this case but don't need to do the substitution. As engineersmnky pointed out in a comment there are other differences ... probably I wouldn't advise this approach because it's not very common
Use a "data object" pattern. This is a little more verbose but more explicit as well:
movies = {
The_Dark_Knight: {
name: "The Dark Knight",
rating: 10
},
Justice_League: {
name: "Justice League",
rating: 1
}
}
movies.each {|key, data|
title_as_string = data[:name]
rating = data[:rating]
# etc
}
This might seem redundant, but it is actually more flexible - what if you stored these movies in the database and wanted to use the ID as the key for the hash instead? That way you could quickly look up records given their ID.
One other thing, you should be using do ... end
for your multiline blocks. Only use braces for oneliner blocks.
Upvotes: 1