ruby - 如何简化此类方法?
问题描述
我有一个班级,有 50 个随机分数的随机人,存储在哈希数组中:
def initialize
# adding fake names and numbers
require 'faker'
@people = []
(1..50).each do
@people << { name: Faker::Name.first_name, score: Faker::Number.between(1, 1000).to_i }
end
end
特别是该top
方法(如下)将返回字符串中排名前 N 的人及其分数。作为 ruby 的新人,我认为可能有一种方法可以让这变得更简单。这是方法:
def top(number=10)
top_people = @people.group_by { |person| person[:score] }
.sort_by { |key, value| -key } # largest -> smallest
.first(number)
.map(&:last)
.flatten
.map { |person| "#{person[:name]} (#{person[:score]})" }
.join(", ")
puts "The top #{number} are here: #{top_people}"
end
供参考,使用 Ruby 2.3.3
解决方案
我也尝试改进其他方面。我错过了更多的背景信息,但是将您的问题作为理论练习来回答,这就是我要做的:
require 'faker'
class ScoredPerson
attr_reader :name
attr_reader :score
def initialize
@name = Faker::Name.first_name
@score = Faker::Number.between(1, 1000).to_i
end
end
class TopPeople
attr_accessor :people
def initialize
@people = 50.times.map do
ScoredPerson.new
end.sort_by { |p| p.score }.reverse
end
def top(number=10)
people.first(number)
.map { |p| "#{p.name} (#{p.score})"}.join(", ")
end
end
- 创建一个有序的人员列表(在一开始)。这将防止在每次调用该
top
方法时进行排序。 - 创建一个
ScoredPerson
类来封装得分人的逻辑。
推荐阅读
- c# - 如何在更新/修改模式下打开 MemoryStream
- ide - QtCreator 是否有另一种选择
- javascript - 为什么 VueJs 原生不支持多选
- elasticsearch - 如何重新加入过期数据的节点
- java - Android 拆分安装错误(-2):Module_Unavailable 错误
- php - “消息”:“未定义属性:Illuminate\Database\Query\Builder::$map”
- r - R stan返回变量“rhs”不存在
- graphql - AND 没有在 GraphQL 中返回结果
- javascript - 将一个值(值是一个对象)从一个对象复制到数组不起作用?
- r - 在R中的cajorls之后提取p值