如何根据对象属性值从Ruby对象列表中筛选指定元素?
问题:筛选总积分等于57的Player对象
问题背景
我从API拉取了一个Player对象列表,输出片段如下(完整内容约300行):
combo => ID: 6, Name:Thomas Partey, Club:1, Position: 3, Price: $4.7, Total Pts: 57 ID: 7, Name:Martin Ødegaard, Club:1, Position: 3, Price: $7.0, Total Pts: 128 ID: 8, Name:Kieran Tierney, Club:1, Position: 2, Price: $4.6, Total Pts: 23 ID: 12, Name:Emile Smith Rowe, Club:1, Position: 3, Price: $5.6, Total Pts: 5
我希望仅展示Total Pts = 57的对象,期望输出:
ID: 6, Name:Thomas Partey, Club:1, Position: 3, Price: $4.7, Total Pts: 57
尝试过的代码
- 第一种写法:
sorted = combo.select{ |item| item[:totalpoints] == 57 } puts sorted
- 第二种写法:
sorted = combo.select(&:totalpoints) == 57
完整代码参考
class Player attr_accessor :id, :firstname, :secondname, :club, :position, :price, :totalpoints, :active def initialize(id, firstname, secondname, club, position, price, totalpoints, active) @id = id.to_i @firstname = firstname.to_s @secondname = secondname.to_s @club = club.to_s @position = position.to_i @price = price / 10.to_f @totalpoints = totalpoints.to_i @active = active.to_i end def to_s() " ID: " + @id.to_s + ", Name:" + @firstname.to_s + " " + @secondname.to_s + ", Club:" + @club.to_s + ", Position: " + @position.to_s + ", Price: $" + @price.to_s + ", Total Pts: " + @totalpoints.to_s + " " end def self.pull() require 'net/http' require 'json' url = 'https://fantasy.premierleague.com/api/bootstrap-static/' uri = URI(url) response = Net::HTTP.get(uri) object = JSON.parse(response) elements = object["elements"] elements.map! { |qb| if qb["chance_of_playing_next_round"].to_f > 0 Player.new( qb["id"], # ID qb["first_name"], # First Name qb["second_name"], # Surname qb["team"], # Club qb["element_type"], # Position qb["now_cost"], # Current Price qb["total_points"], # Total Points qb["chance_of_playing_next_round"]) # Chance Of Playing end } end combo = Player.pull().map{|qb| qb}
解决方案
你的问题出在两个核心点:
- 属性访问方式错误:Player类用
attr_accessor定义的是实例属性,不能用哈希键item[:totalpoints]访问,必须用点语法item.totalpoints。 - 第二种写法逻辑完全错误:
combo.select(&:totalpoints)会筛选出所有totalpoints非空的对象,之后和57比较得到的是布尔值,完全达不到筛选目的。
正确的筛选代码:
# 先过滤掉pull方法返回的nil元素 combo = Player.pull().compact # 筛选总积分等于57的球员 filtered_players = combo.select { |player| player.totalpoints == 57 } # 逐个输出符合条件的对象 filtered_players.each { |player| puts player }
内容的提问来源于stack exchange,提问作者ldthompson
相关产品推荐
相关产品推荐

