Kelvin De Moya
Kelvin De Moya

Reputation: 5694

Sort array based on another array and then on date

I'd like to know, I have an array of "Movie" objects with properties like production studio and release dates.

I'd like to sort the Array of objects based first on the on the ranking of the production studio and then on the date of each movie.

For Example:

studio_ratings = [Studio1, Studio2, Studio3, Studio4, Studio5]

array_of_objects = [Object1, Object2, Object3, Object4, Object5, Object6, Object7, Object8, Object9]

Each object have its date, so I can so Object1.date_published and Object1.production_studio, for example.

Upvotes: 0

Views: 86

Answers (1)

glenn mcdonald
glenn mcdonald

Reputation: 15478

I assume you mean that studio_ratings is the order you wish the studios to be ranked in. In which case you can do something like:

array_of_objects.sort_by {|obj| [studio_ratings.index(obj.production_studio), obj.date_published]}

But if you're doing lots of these, or the list of studios is long, you'd be better off constructing a hash instead of doing .index over and over. E.g.:

>> studio_rankings = ['Universal', 'Global', 'Local', 'Wolverine']
=> ["Universal", "Global", "Local", "Wolverine"]
>> class Film
>>   attr_accessor :studio, :date
>>   def initialize(studio, date)
>>     @studio = studio
>>     @date = date
>>   end
>> end
=> nil
>> films = [Film.new('Global', '2012-01-01'), Film.new('Universal', '2013-04-12'), Film.new('Global', '2011-10-10'), Film.new('Wolverine', '2008-01-01')]
=> [#<Film:0x101b101a0 @date="2012-01-01", @studio="Global">, #<Film:0x101b10128 @date="2013-04-12", @studio="Universal">, #<Film:0x101b100b0 @date="2011-10-10", @studio="Global">, #<Film:0x101b10038 @date="2008-01-01", @studio="Wolverine">]
>> films.sort_by {|f| [studio_rankings.index(f.studio), f.date]}
=> [#<Film:0x101b10128 @date="2013-04-12", @studio="Universal">, #<Film:0x101b100b0 @date="2011-10-10", @studio="Global">, #<Film:0x101b101a0 @date="2012-01-01", @studio="Global">, #<Film:0x101b10038 @date="2008-01-01", @studio="Wolverine">]
>> studio_index = {}
=> {}
>> studio_rankings.each_with_index {|studio, i| studio_index[studio] = i}
=> ["Universal", "Global", "Local", "Wolverine"]
>> studio_index
=> {"Local"=>2, "Wolverine"=>3, "Global"=>1, "Universal"=>0}
>> films.sort_by {|f| [studio_index[f.studio], f.date]}
=> [#<Film:0x101b10128 @date="2013-04-12", @studio="Universal">, #<Film:0x101b100b0 @date="2011-10-10", @studio="Global">, #<Film:0x101b101a0 @date="2012-01-01", @studio="Global">, #<Film:0x101b10038 @date="2008-01-01", @studio="Wolverine">]

Upvotes: 1

Related Questions