从对象列表中按对象属性值选择。

huangapple go评论54阅读模式
英文:

Select from list of objects by object attribute value?

问题

我有一个从API中拉取的对象列表。以下是输出的一部分(因为有大约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 

我想只显示总分等于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

如果需要完整的代码,请提供。

类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}

英文:

I have a list of objects that are pulled in from an API. Here is the snippet of output (as there's about 300 lines):

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 

I would like to only show the combo where Total Pts = 57

So desired output is just:

ID: 6, Name:Thomas Partey, Club:1, Position: 3, Price: $4.7, Total Pts: 57

I've tried the following:

sorted = combo.select{ |item| item[:totalpoints] == 57 }
puts sorted

and

sorted = combo.select(&:totalpoints) == 57

Full code is here if needed:

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}

答案1

得分: 1

看着你的示例数据,你需要在combo中的每个元素上调用totalpoints方法,然后与你想要的进行比较:

combo.compact.select { |element| element.totalpoints == 57 }

compact的使用是为了删除那些为nil的元素,否则当在一个未定义在Nil对象上的方法上调用时,你将会得到一个异常(这是我能想到的最简单的方法,可能还有其他方法)。

请注意,以下代码不会按预期工作:

combo.select(&:totalpoints) == 57

因为当在它上调用totalpoints方法时,select将会为每个具有"truthy"值的元素产生true。然后将比较这个结果与57,这永远不会按预期工作,因为给定的结果可能是一个数组或一个哈希表。

英文:

Looking at the data from your example you'll need to invoke the totalpoints method on each element in combo and then compare it with what you want;

combo.compact.select { |element| element.totalpoints == 57  }

The compact use is to remove the elements that are nil otherwise you'll get an exception when invoking a method that hasn't been defined on a Nil object (that's the easiest way I could think of, there might be others).

Notice this won't work as expected;

combo.select(&:totalpoints) == 57

because select will be yielding true for every element with a "truthy" value when the method totalpoints is invoked on it. And that result will then be compared to 57 which will never work as intended because the given result might be an array or a hash.

huangapple
  • 本文由 发表于 2023年2月24日 00:26:20
  • 转载请务必保留本文链接:https://go.coder-hub.com/75547608.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定