我想从数据库中的电影中获取评级并返回一系列独特评级,按以下顺序排序:
G PG PG-13 R NC-17
普通Array#sort
还不够:
["PG-13", "PG", "NC-17", "G", "R"].sort
# => ["G", "NC-17", "PG", "PG-13", "R"]
以下代码为我提供了我想要的内容,但似乎有更好的方法来编写它而不必使用delete
和<<
。任何想法都将不胜感激。
class Movie < ActiveRecord::Base
def self.all_ratings
allRatings = []
Movie.all.each do |movie|
unless allRatings.include?(movie.rating)
allRatings << movie.rating
end
end
if allRatings.include?("NC-17")
allRatings.sort!
allRatings.delete("NC-17")
allRatings << "NC-17"
return allRatings
else
return allRatings.sort
end
end
end
更新: 使用Sergio的提示,我能够重构代码。如果有人有其他想法,我会很感激反馈。
class Movie < ActiveRecord::Base
def self.all_ratings
allRatings = []
Movie.all.each do |movie|
unless allRatings.include?(movie.rating)
allRatings << movie.rating
end
end
allRatings.sort_by! {|t| t == 'NC-17' ? 'ZZZ' : t}
end
end
更新:
使用ByScripts提示,此代码运行良好且非常简洁。我不得不从Rails 3.1.0升级到Rails 3.2.8以获得pluck
方法。看起来它是在3.2.1中引入的。
我还必须添加.sort
才能获得所需的输出。
class Movie < ActiveRecord::Base
def self.all_ratings
all_ratings = Movie.pluck(:rating).uniq.sort# don't retrieve unnecessary datas
all_ratings << all_ratings.delete('NC-17') # directly inject NC-17 at the end if exists
all_ratings.compact # remove nil values
end
end
答案 0 :(得分:2)
你可以使用这个小技巧
sorted = ["PG-13", "PG", "NC-17", "G", "R"].sort_by {|t| t == 'NC-17' ? 'ZZZ' : t }
sorted # => ["G", "PG", "PG-13", "R", "NC-17"]
基本上,出于分类目的,您可以将“NC-17”替换为最后排序的“ZZZ”。
答案 1 :(得分:2)
这应该有效:
def self.all_ratings
all_ratings = Movies.order(:rating).pluck(:rating).uniq # don't retrieve unnecessary datas
all_ratings << all_rating.delete('NC-17') # directly inject NC-17 at the end if exists
all_ratings.compact # remove nil values
end
您也可以Movies.uniq.pluck(:rating)
执行SELECT DISTINCT
查询(其中pluck.uniq
过滤数组)。不知道是否存在性能影响(可能是内存占用较少?)。
无论如何,两者都应该是一样的。
答案 2 :(得分:1)
我喜欢塞尔吉奥的伎俩,但是如果您正在寻找原始代码的更简单版本,但仍有delete
和<<
,请尝试使用
def sort(ratings)
ratings.sort!
return ratings unless ratings.include?("NC-17")
ratings.delete("NC-17")
ratings << "NC-17"
end
答案 3 :(得分:1)
class Movie < ActiveRecord::Base
RatingOrder = %w[G PG PG-13 R NC-17]
def self.all_ratings
RatingOrder & Movie.all.map(&:rating)
end
end