Home > Back-end >  Return Elements in the array that start with a specific letter e.g D
Return Elements in the array that start with a specific letter e.g D

Time:04-13

I am having issue with my code below. I am new to ruby. I want to return names that only start with the letter D but it just returns all the names. When I try the .start_with? method it returns an error message "undefined method .start_with?". Any help would be amazing, thank you

students = [
  {name: "Dr. Hannibal Lecter", cohort: :november},
  {name: "Darth Vader", cohort: :november},
  {name: "Nurse Ratched", cohort: :november},
  {name: "Michael Corleone", cohort: :november},
  {name: "Alex DeLarge", cohort: :november},
  {name: "The Wicked Witch of the West", cohort: :november},
  {name: "Terminator", cohort: :november},
  {name: "Freddy Krueger", cohort: :november},
  {name: "The Joker", cohort: :november},
  {name: "Joffrey Baratheon", cohort: :november},
  {name: "Norman Bates", cohort: :november}
]

students.each{ |x| puts x if x[0] == 'D' }

CodePudding user response:

You are sending a message to a Hash for it to respond when it start_with? a "D". But a Hash does not have a start_with? method - so it gives you the error message.

You are looking for a specific key (:name) in a hash, so you'll have to specify which key:

   students.each{ |x| puts x if x[:name].start_with? 'D' }

CodePudding user response:

Your Block Variable is an Array, Not a Hash

In your existing code, you are assigning each element of the array to x, but the variable your comparing is a Hash rather than an Array. What you actually want to do is iterate through the Hash objects in your Array, and then check each String assigned to the :name key for that Hash rather than the value of a non-existent key of 0. For example, using Ruby 3.1.1 with the Array#select method:

students.select { |hash| hash[:name].start_with? 'D' }
#=> 
[{:name=>"Dr. Hannibal Lecter", :cohort=>:november},                            
 {:name=>"Darth Vader", :cohort=>:november}]  

However, note that the results will return:

  1. The whole Hash that matches your Array#select statement.
  2. Won't differentiate between names and titles. It's just looking and the value of the key for the first letter, so you might need additional code to handle titles, suffixes like Jr. or Sr., and so forth if you're trying to properly alphabetize a list of names.

That may not matter for your immediate purposes, but these caveats are worth pointing out for future reference.

Extract Just the Names

If you just want the name, and not the whole Hash, then you can use Array#map to return just the value from the matching Hash key when a match is found, and chain it to Array#compact which will remove any nil values in the Array returned by the Array#map method. For example:

students.map do |hash|
  hash[:name] if hash[:name].start_with? 'D'
end.compact
#=> ["Dr. Hannibal Lecter", "Darth Vader"]
  • Related