Ивайло обнови решението на 30.10.2011 23:14 (преди около 13 години)
+class Song
+ attr_reader :name
+ attr_reader :artist
+ attr_reader :genre
+ attr_reader :subgenre
+ attr_reader :tags
+ def initialize attributes
+ @name = if attributes[0] != nil then attributes[0].strip end
+ @artist = if attributes[1] != nil then attributes[1].strip end
+ @genre = if attributes[2] != nil then (attributes[2].split ",") [0].strip end
+ @subgenre = if attributes[2] != nil then (attributes[2].split ",") [1] end
+ if @subgenre != nil then @subgenre.strip! end
+ if @genre != nil then @tags = Array (@genre.downcase) end
+ if @subgenre != nil then @tags << @subgenre.downcase.strip end
+ if attributes[3] != nil
+ (attributes[3].split ",").each { |tag| @tags << tag.strip }
+ end
+ end
+
+ def matchesCriteria? criteria
+ all_tags = Array(criteria[:tags])
+ anti_tags = all_tags.map { |tag| tag.dup}.delete_if {|tag| !tag.end_with? "!"}
+ tags = all_tags - anti_tags
+ anti_tags.each { |anti_tag| anti_tag.slice! anti_tag.length - 1}
+ return (@tags & anti_tags == []) && (tags & @tags == tags) &&
+ (criteria[:name] == nil || @name == criteria[:name]) &&
+ (criteria[:artist] == nil || @artist == criteria[:artist]) &&
+ (criteria[:filter] == nil || (criteria[:filter].call (self)))
+ end
+end
+
+class Collection
+ def initialize songs_as_string, artist_tags
+ @songs = []
+ make_songs songs_as_string
+ add_artist_tags artist_tags
+ end
+
+ def find criteria
+ if criteria == {}
+ return @songs
+ end
+ result = []
+ @songs.each do |song|
+ if song.matchesCriteria? criteria
+ result << song
+ end
+ end
+ result
+ end
+
+ private
+
+ def make_songs songs_as_string
+ songs_as_string.lines do |line|
+ @songs << (Song.new (line.chomp.split '.'))
+ end
+ end
+
+ def add_artist_tags artist_tags
+ if artist_tags == nil
+ return
+ end
+ artist_tags.each do |k, v|
+ @songs.select { |song| song.artist == k }.each do |s|
+ v.each { |tag| s.tags << tag}
+ end
+ end
+ end
+end