arraysrubyruby-hash

How to extract all values from a key that are inside a hash


I ask a user for input, and store it as hashes inside an array. I need to extract the values that share the same key from those hashes. I want to print the names of students that belong to the same cohort like this:

"May cohort students are: Brian, Penelope"
"June cohort students are: Fred, Pedro"

How could I do this? I need help with this method:

def print(students)
  #go through all hashes in 'students' and group them by cohort
  #print each cohort separately
end

so that I can do using map and select:

def input_students
  puts "Please enter the names of the students"
  puts "To finish, just hit return twice"
  students = []
  name = gets.chomp
  puts "In which cohort is this student?"
  cohort = gets.chomp 
  while !name.empty? do
    students << {cohort.to_sym => name}
    name = gets.chomp
    cohort = gets.chomp
  end
  students
end

students = input_students
print(students)

But I get:

"no implicit conversion of Symbol to Integer"

Solution

  • Firstly I suggest to change input_students because the proposal to enter the name and cohort is displayed only once. And user can't understand what ot enter.

    Also I suggest to change the return value of this method.

    def input_students
      puts "Leave field empty to finish"
      puts
    
      students = []
    
      loop do
        puts "Please enter the name of the student"
        name = gets.chomp
        break if name.empty?
    
        puts "In which cohort is this student?"
        cohort = gets.chomp
        break if cohort.empty?
    
        students << { cohort: cohort, name: name }
      end
    
      students
    end
    
    def print(students)
      students.
        map { |s| s[:cohort] }.
        uniq.
        each { |c| puts "#{c} cohort students are #{students.
                                                      find_all { |s| s[:cohort] == c }.
                                                      map { |s| s[:name] }.
                                                      join(', ')}" }
    end
    
    students = input_students
    print(students)
    
    # First we get an array of cohorts of all students.
    # The number of elements in the array is equal to the number of students
    students.map { |s| s[:cohort] }
    
    # But many students are in the same cohort.
    # To avoid this duplication, get rid of duplicates.
    students.map { |s| s[:cohort] }.uniq
    
    # Well done. Now we have an array of unique cohorts.
    # We can use this to print information about each cohort.
    students.map { |s| s[:cohort] }.uniq.each { |c| puts "Cohort information" }
    
    # How to print information? For each cohort certain actions are carried out.
    
    # First, find all the students in this cohort.
    students.find_all { |s| s[:cohort] == c }
    
    # We only need the names of these students.
    students.find_all { |s| s[:cohort] == c }.map { |s| s[:name] }
    
    # But this is an array of names. Convert it to a string, separated by commas.
    students.find_all { |s| s[:cohort] == c }.map { |s| s[:name] }.join(', ')