Венета обнови решението на 31.10.2011 00:27 (преди около 13 години)
+class Song
+ attr_accessor :name, :artist, :genre, :subgenre, :tags
+ def initialize(args, artist_tags)
+ @name, @artist = args[0], args[1]
+ genre_arr = args[2].split(',')
+ @genre = genre_arr[0].strip
+ @subgenre = genre_arr[1] ? genre_arr[1].strip : nil
+ @tags = args[3] ? args[3].split(',').map { |tag| tag.strip } : []
+ tags_by_artist(artist_tags)
+ tags_by_genre()
+ end
+
+ def tags_by_artist(artist_tags)
+ artist_tags[@artist].each do |tag|
+ @tags.push(tag)
+ end if artist_tags.has_key?(@artist)
+ end
+
+ def tags_by_genre()
+ @tags.push(@genre.downcase) if @genre
+ @tags.push(@subgenre.downcase) if @subgenre
+ end
+
+ def has_tags?(tags)
+ Array(tags).each do |tag|
+ if tag.end_with?('!')
+ return false if @tags.include? tag[0..-2]
+ else
+ return false unless @tags.include? tag
+ end
+ end
+ true
+ end
+
+ def name? (name)
+ @name == name ? true : false
+ end
+
+ def artist? (artist)
+ @artist == artist ? true : false
+ end
+
+ def has_filter? (&block)
+ block.(self)
+ end
+end
+
+class Collection
+ def initialize(songs_as_string, artist_tags)
+ @songs_collection = songs_as_string.lines.map do |line|
+ Song.new(line.split('.').map { |item| item.strip }, artist_tags)
+ end
+ end
+
+ def find(criteria)
+ result = @songs_collection.dup
+ if criteria[:tags]
+ result = result.select { |song| song.has_tags? criteria[:tags] }
+ end
+ if criteria[:name]
+ result = result.select { |song| song.name? criteria[:name] }
+ end
+ if criteria[:artist]
+ result = result.select { |song| song.artist? criteria[:artist] }
+ end
+ if criteria[:filter]
+ result = result.select { |song| song.has_filter? &criteria[:filter] }
+ end
+ result
+ end
+end