0

データベース内の映画から評価を取得し、次の順序で並べ替えられた一意の評価の配列を返したいと考えています。

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次のコードは私が望むものを与えてくれますが、 andを使用せずに記述するより良い方法があるよう<<です。どんなアイデアでも大歓迎です。

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
4

4 に答える 4

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配列をフィルタリングする場所)。パフォーマンスへの影響があるかどうかはわかりません (おそらく、メモリ フットプリントが小さくなるのでしょうか?)。

とにかく、どちらも同じように動作するはずです。

于 2013-01-28T20:35:25.693 に答える
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」に置き換えます。

于 2013-01-28T19:31:12.337 に答える
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
于 2013-01-31T09:12:14.497 に答える
1

私はセルジオのトリックが好きですが、元のコードの単純なバージョンを探していて、まだdeleteandがある場合は<<、これを試してください

def sort(ratings)
  ratings.sort!
  return ratings unless ratings.include?("NC-17")

  ratings.delete("NC-17")

  ratings << "NC-17"
end
于 2013-01-28T19:35:32.397 に答える