如何在 ruby 中使用方法参数作为变量
How to use Method param as variable in ruby
你好,我的 ruby 有一个问题,它说我的参数没有初始化,你能帮我吗?我需要对所有科目求和
class Student
attr_accessor :name, :english, :math, :science, :french, :pe
def initialize(name, english, math, science, french, pe)
@name = name
@english = english
@math = math
@science = science
@french = french
@pe = pe
end
def avg_sum_grades(param)
sum_of_subjcet_grades = students.map { |student| student.param }
end
students = [
student.new('brian', 3, 4, 5, 5, 6),
student.new('eric', 1, 3, 4, 5, 2),
student.new('jessica', 2, 1, 4, 5, 3),
student.new('agatha', 4, 4, 5, 3, 5),
student.new('alex', 2, 4, 5, 2, 5)
]
avg_sum_grades("english")
您正在尝试访问基于传递给方法的 名称 的方法。
class Student
attr_accessor :name, :english, :math, :science, :french, :pe
def initialize(name, english, math, science, french, pe)
@name = name
@english = english
@math = math
@science = science
@french = french
@pe = pe
end
end
这绝对可以通过使用带有 #send
方法的符号来实现。
bob = Student.new("Bob", 1, 2, 3, 4, 5)
bob.send(:pe)
# => 5
您正在尝试对一组 Student
个对象执行此操作。
students = [
student.new('brian', 3, 4, 5, 5, 6),
student.new('eric', 1, 3, 4, 5, 2),
student.new('jessica', 2, 1, 4, 5, 3),
student.new('agatha', 4, 4, 5, 3, 5),
student.new('alex', 2, 4, 5, 2, 5)
]
所以你可以这样写:
def get_avg_grade(students, subject)
grades = students.map { |s| s.send(subject) }
grades.sum / grades.length
end
可以调用:get_avg_grade(students, :math)
.
还有一件事...
鉴于您只是为所有内容创建访问器,您真的可以只写:
Student = Struct.new(:name, :english, :math, :science, :french, :pe)
您将需要 instance_variable_get
来获取字符串形式的实例变量。
class Student
attr_accessor :name, :english, :math, :science, :french, :pe
def initialize(name, english, math, science, french, pe)
@name = name
@english = english
@math = math
@science = science
@french = french
@pe = pe
end
end
@students = [
Student.new('brian', 3, 4, 5, 5, 6),
Student.new('eric', 1, 3, 4, 5, 2),
Student.new('jessica', 2, 1, 4, 5, 3),
Student.new('agatha', 4, 4, 5, 3, 5),
Student.new('alex', 2, 4, 5, 2, 5)
]
def avg_sum_grades(param)
sum_of_subjcet_grades = @students.sum{ |student| student.instance_variable_get("@#{param}") }
end
avg_sum_grades("english")
我的答案的显着特点是它不要求所有学生都选修过相同的课程。
我想到下面的例子来创建classStudent
的实例:
Student.new('eric', english: 1, math: 3, french: 5, pe: 2),
请注意 Eric 尚未注册科学。
class Student
attr_accessor :name, :grades
def initialize(name, **grades)
@name = name
@grades = grades
end
end
def avg_grade(students, subject)
avg(students.filter_map do |student|
student.grades[subject] if student.grades.key?(subject)
end)
end
def avg(arr)
arr.sum.fdiv(arr.size).round(1)
end
参见 Double-Splat, Enumerable#filter_map and Numeric#fdiv and Numeric#round。
让我们创建一些学生。
students = [
Student.new('brian', english: 3, math: 4, science: 5, french: 5, pe: 6),
Student.new('eric', english: 1, math: 3, french: 5, pe: 2),
Student.new('jessica', math: 1, science: 4, french: 5, pe: 3),
Student.new('agatha', english: 4, science: 5, french: 3, pe: 5),
Student.new('alex', english: 2, math: 4, french: 2, pe: 5)
]
让我们看看我们有什么。
students.each { |student| puts "@name = #{student.name}, @grades = #{student.grades}" }
@name = brian, @grades = {:english=>3, :math=>4, :science=>5, :french=>5, :pe=>6}
@name = eric, @grades = {:english=>1, :math=>3, :french=>5, :pe=>2}
@name = jessica, @grades = {:math=>1, :science=>4, :french=>5, :pe=>3}
@name = agatha, @grades = {:english=>4, :science=>5, :french=>3, :pe=>5}
@name = alex, @grades = {:english=>2, :math=>4, :french=>2, :pe=>5}
现在按学科计算平均成绩。为此,我们首先构建一个由至少一名学生选修的所有科目组成的数组:
subjects = students.reduce([]) { |subs, student| subs | student.grades.keys }
#=> [:english, :math, :science, :french, :pe]
然后按学科显示平均成绩:
subjects.each { |subject| puts "#{subject}: #{avg_grade(students, subject)}" }
english: 2.5
math: 3.0
science: 4.7
french: 4.0
pe: 4.2
参见 Array#|。
即使所有学生都选修相同的五门科目,也可以说
Student.new('brian', english: 3, math: 4, science: 5, french: 5, pe: 6)
会比
少error-prone
Student.new('brian', 3, 4, 5, 5, 6)
据了解,成绩分别针对英语、数学、科学、法语和 PE。当然,如果成绩是从外部来源以这种格式提供的,那么就无法选择如何表达论点。
你好,我的 ruby 有一个问题,它说我的参数没有初始化,你能帮我吗?我需要对所有科目求和
class Student
attr_accessor :name, :english, :math, :science, :french, :pe
def initialize(name, english, math, science, french, pe)
@name = name
@english = english
@math = math
@science = science
@french = french
@pe = pe
end
def avg_sum_grades(param)
sum_of_subjcet_grades = students.map { |student| student.param }
end
students = [
student.new('brian', 3, 4, 5, 5, 6),
student.new('eric', 1, 3, 4, 5, 2),
student.new('jessica', 2, 1, 4, 5, 3),
student.new('agatha', 4, 4, 5, 3, 5),
student.new('alex', 2, 4, 5, 2, 5)
]
avg_sum_grades("english")
您正在尝试访问基于传递给方法的 名称 的方法。
class Student
attr_accessor :name, :english, :math, :science, :french, :pe
def initialize(name, english, math, science, french, pe)
@name = name
@english = english
@math = math
@science = science
@french = french
@pe = pe
end
end
这绝对可以通过使用带有 #send
方法的符号来实现。
bob = Student.new("Bob", 1, 2, 3, 4, 5)
bob.send(:pe)
# => 5
您正在尝试对一组 Student
个对象执行此操作。
students = [
student.new('brian', 3, 4, 5, 5, 6),
student.new('eric', 1, 3, 4, 5, 2),
student.new('jessica', 2, 1, 4, 5, 3),
student.new('agatha', 4, 4, 5, 3, 5),
student.new('alex', 2, 4, 5, 2, 5)
]
所以你可以这样写:
def get_avg_grade(students, subject)
grades = students.map { |s| s.send(subject) }
grades.sum / grades.length
end
可以调用:get_avg_grade(students, :math)
.
还有一件事...
鉴于您只是为所有内容创建访问器,您真的可以只写:
Student = Struct.new(:name, :english, :math, :science, :french, :pe)
您将需要 instance_variable_get
来获取字符串形式的实例变量。
class Student
attr_accessor :name, :english, :math, :science, :french, :pe
def initialize(name, english, math, science, french, pe)
@name = name
@english = english
@math = math
@science = science
@french = french
@pe = pe
end
end
@students = [
Student.new('brian', 3, 4, 5, 5, 6),
Student.new('eric', 1, 3, 4, 5, 2),
Student.new('jessica', 2, 1, 4, 5, 3),
Student.new('agatha', 4, 4, 5, 3, 5),
Student.new('alex', 2, 4, 5, 2, 5)
]
def avg_sum_grades(param)
sum_of_subjcet_grades = @students.sum{ |student| student.instance_variable_get("@#{param}") }
end
avg_sum_grades("english")
我的答案的显着特点是它不要求所有学生都选修过相同的课程。
我想到下面的例子来创建classStudent
的实例:
Student.new('eric', english: 1, math: 3, french: 5, pe: 2),
请注意 Eric 尚未注册科学。
class Student
attr_accessor :name, :grades
def initialize(name, **grades)
@name = name
@grades = grades
end
end
def avg_grade(students, subject)
avg(students.filter_map do |student|
student.grades[subject] if student.grades.key?(subject)
end)
end
def avg(arr)
arr.sum.fdiv(arr.size).round(1)
end
参见 Double-Splat, Enumerable#filter_map and Numeric#fdiv and Numeric#round。
让我们创建一些学生。
students = [
Student.new('brian', english: 3, math: 4, science: 5, french: 5, pe: 6),
Student.new('eric', english: 1, math: 3, french: 5, pe: 2),
Student.new('jessica', math: 1, science: 4, french: 5, pe: 3),
Student.new('agatha', english: 4, science: 5, french: 3, pe: 5),
Student.new('alex', english: 2, math: 4, french: 2, pe: 5)
]
让我们看看我们有什么。
students.each { |student| puts "@name = #{student.name}, @grades = #{student.grades}" }
@name = brian, @grades = {:english=>3, :math=>4, :science=>5, :french=>5, :pe=>6}
@name = eric, @grades = {:english=>1, :math=>3, :french=>5, :pe=>2}
@name = jessica, @grades = {:math=>1, :science=>4, :french=>5, :pe=>3}
@name = agatha, @grades = {:english=>4, :science=>5, :french=>3, :pe=>5}
@name = alex, @grades = {:english=>2, :math=>4, :french=>2, :pe=>5}
现在按学科计算平均成绩。为此,我们首先构建一个由至少一名学生选修的所有科目组成的数组:
subjects = students.reduce([]) { |subs, student| subs | student.grades.keys }
#=> [:english, :math, :science, :french, :pe]
然后按学科显示平均成绩:
subjects.each { |subject| puts "#{subject}: #{avg_grade(students, subject)}" }
english: 2.5
math: 3.0
science: 4.7
french: 4.0
pe: 4.2
参见 Array#|。
即使所有学生都选修相同的五门科目,也可以说
Student.new('brian', english: 3, math: 4, science: 5, french: 5, pe: 6)
会比
少error-proneStudent.new('brian', 3, 4, 5, 5, 6)
据了解,成绩分别针对英语、数学、科学、法语和 PE。当然,如果成绩是从外部来源以这种格式提供的,那么就无法选择如何表达论点。