是否可以根据单个对象对方法的响应来对对象列表进行排序? [英] Is it possible to sort a list of objects depending on the individual object's response to a method?

查看:58
本文介绍了是否可以根据单个对象对方法的响应来对对象列表进行排序?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我想展示一个产品的图库,其中包括既可以出售也可以出售的产品。只有我希望将要出售的产品出现在列表的顶部,而将不出售的对象显示在列表的末尾。

I am wanting to display a gallery of products where I include products that are both for sale and not for sale. Only I want the products that are for sale to appear at the front of the list and the objects that are not for sale will appear at the end of the list.

完成此操作的一种简单方法是创建两个列表,然后合并它们(一个on_sale?对象列表和一个非on_sale?对象列表):

An easy way for me to accomplish this is to make two lists, then merge them (one list of on_sale? objects and one list of not on_sale? objects):

available_products = []
sold_products = []
@products.each do |product|
  if product.on_sale?
    available_products << product
  else
    sold_products << product
  end
end

。 。 。但是对现有应用程序的结构进行操作,由于我的代码很奇怪,这将需要大量的重构(我失去了分页,我宁愿不重构)。如果有一种方法可以通过我的产品模型的方法 on_sale?对现有对象列表进行排序,这会更容易返回布尔值。

. . . But do to the structure of my existing app, this would require an excessive amount of refactoring due to an oddity in my code (I lose my pagination, and I would rather not refactor). It would be easier if there were a way to sort the existing list of objects by my product model's method on_sale? which returns a boolean value.

是否可以更优雅地遍历现有列表并按rails中的此true或false值对其进行排序?我只想问一问,因为在这种框架/语言(红宝石)中没有太多隐藏的东西,我想知道它们是否已经在我之前完成了。

Is it possible to more elegantly iterate through an existing list and sort it by this true or false value in rails? I only ask because there is so much I'm not aware of hidden within this framework / language (ruby) and I'd like to know if they work has been done before me.

推荐答案

可以。理想情况下,我们将使用 sort_by!

Sure. Ideally we'd do something like this using sort_by!:

@products.sort_by! {|product| product.on_sale?}

或时髦的人

@products.sort_by!(&:on_sale?)

但可悲的是,< => 不适用于布尔值(请参阅)和 sort_by 不适用于布尔值,因此我们需要使用此技巧(感谢rohit89!)

but sadly, <=> doesn't work for booleans (see Why doesn't sort or the spaceship (flying saucer) operator (<=>) work on booleans in Ruby?) and sort_by doesn't work for boolean values, so we need to use this trick (thanks rohit89!)

@products.sort_by! {|product| product.on_sale? ? 0 : 1}






如果您想获得更出色的服务, sort 方法采用一个代码块,在该代码块内,您可以使用所需的任何逻辑,包括类型转换和多个键。试试这样的事情:


If you want to get fancier, the sort method takes a block, and inside that block you can use whatever logic you like, including type conversion and multiple keys. Try something like this:

@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放在a之前是因为您想要 true 值要早于 false

(putting b before a because you want "true" values to come before "false")

或者,如果您有第二种排序方式:

or if you have a secondary sort:

@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 返回一个新集合,该集合通常是一种更干净,更不易出错的解决方案,但是 sort! 修改原始集合的内容,您说这是必需的。

Note that sort returns a new collection, which is usually a cleaner, less error-prone solution, but sort! modifies the contents of the original collection, which you said was a requirement.

这篇关于是否可以根据单个对象对方法的响应来对对象列表进行排序?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆