ruby – 是否可以根据单个对象对方法的响应对对象列表进行排序?
我想展示一个产品的画廊,其中包括出售和不出售的产品.只有我想要出售的产品出现在列表的前面,并且不出售的对象将显示在列表的末尾.
一个简单的方法可以让我完成这个工作就是做两个列表,然后合并它们(一个on_sale?对象列表和一个不是on_sale?对象的列表): available_products = [] sold_products = [] @products.each do |product| if product.on_sale? available_products << product else sold_products << product end end . . .但是,对于我现有的应用程序的结构,这将需要过多的重构,因为我的代码很奇怪(我失去了我的分页,我宁愿不重构).如果有办法通过我的产品型号的方法on_sale对现有的对象列表进行排序会更容易吗?它返回一个布尔值. 是否可以通过现有的列表更加优雅地迭代,并通过rails中的真实或虚假值进行排序?我只是问,因为有这么多我不知道隐藏在这个框架/语言(ruby),我想知道他们的工作是否已经在我之前完成. 解决方法
当然.理想情况下,我们将使用
sort_by! 做这样的事情:
@products.sort_by! {|product| product.on_sale?} 或者snazzier @products.sort_by!(&:on_sale?) 但可悲的是,< =不适用于布尔值(参见Why doesn’t sort or the spaceship (flying saucer) operator (<=>) work on booleans in Ruby?),sort_by不适用于布尔值,因此我们需要使用这个技巧(谢谢rohit89!) @products.sort_by! {|product| product.on_sale? ? 0 : 1} 如果您想获得优势,则排序方法会占用一个块,并且在该块内,您可以使用任何您喜欢的逻辑,包括类型转换和多个键.尝试这样的东西: @products.sort! do |a,b| a_value = a.on_sale? ? 0 : 1 b_value = b.on_sale? ? 0 : 1 a_value <=> b_value end 或这个: @products.sort! do |a,b| b.on_sale?.to_s <=> a.on_sale?.to_s end (把b放在前面,因为你想要“真”值出现在“假”之前) 或者如果您有次要排序: @products.sort! do |a,b| if a.on_sale? != b.on_sale? b.on_sale?.to_s <=> a.on_sale?.to_s else a.name <=> b.name end end 请注意,sort返回一个新的集合,通常是一个更干净,更容易出错的解决方案,但是 (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |