Мартин обнови решението на 30.10.2011 23:51 (преди около 13 години)
+class Song
+ attr_reader :name, :artist, :genre, :subgenre, :tags
+ def initialize(name, artist, genre, subgenre, tags)
+ @name = name
+ @artist = artist
+ @genre = genre
+ @subgenre = subgenre
+ @tags = tags
+ end
+end
+
+class Collection
+ def initialize(songs_as_string, artist_tags)
+ @songs = []
+ songs_as_string.each_line do |line|
+ name, artist, genre, tags = line.split('.').map(&:strip)
+ genre, subgenre = genre.include?(',') ? genre.split(', ') : genre
+ tags = tags.nil? ? [] : tags.split(', ')
+ [genre, subgenre].each { |el| tags << el.downcase unless el.nil? }
+ tags |= artist_tags.fetch(artist, [])
+ @songs << Song.new(name, artist, genre, subgenre, tags)
+ end
+ end
+
+ def find_tags(tags)
+ without_tags = tags.select{ |tag| tag.end_with?('!') }
+ wanted_tags = tags - without_tags
+ @songs.select do |song|
+ (wanted_tags - (song.tags & wanted_tags)).empty? and \
+ (song.tags & without_tags.map(&:chop)).empty?
+ end
+ end
+
+ def find(criteria)
+ search_result = @songs.dup
+ criteria.each do |key, value|
+ search_result &= case key
+ when :name then @songs.select { |song| song.name == value }
+ when :artist then @songs.select { |song| song.artist == value }
+ when :tags then find_tags(Array(value))
+ when :filter then @songs.select(&value)
+ end
+ end
+ search_result
+ end
+end