Веселин обнови решението на 30.10.2011 23:29 (преди около 13 години)
+class Song
+ attr_accessor :name, :artist, :genre, :subgenre, :tags
+
+ def initialize(name, artist, genre, subgenre, tags)
+ @name, @artist, @genre = name, artist, genre
+ @tags, @subgenre = tags, subgenre
+ end
+
+ def match_criteria?(criteria = {})
+ criteria.all? { |k, v| check_criteria_pair(k, v) }
+ end
+
+ private
+
+ def check_criteria_pair(key, value)
+ case key
+ when :name then @name == value
+ when :artist then @artist == value
+ when :genre then @genre == value
+ when :subgenre then @subgenre == value
+ when :tags then match_tags?(Array(value))
+ when :filter then value.call(self)
+ end
+ end
+
+ def match_tags?(tags)
+ tags.all? do |tag|
+ if tag.end_with?("!")
+ not @tags.include?(tag.chop)
+ else
+ @tags.include?(tag)
+ end
+ end
+ end
+end
+
+class Collection
+
+ def initialize(songs_as_string, artist_tags)
+ @songs = songs_as_string.lines.map do |line|
+ song = parse_song(line)
+ if (artist_tags.has_key?(song.artist))
+ song.tags = (song.tags + artist_tags[song.artist].map(&:downcase)).uniq
+ end
+ song
+ end
+ end
+
+ def find(criteria)
+ @songs.select { |song| song.match_criteria?(criteria) }
+ end
+
+ private
+
+ def parse_song(song_as_string)
+ song_attrs = song_as_string.split('.').map(&:strip)
+ genre_attrs = song_attrs[2].split(',').map(&:strip)
+ genre = genre_attrs[0]
+ subgenre = genre_attrs[1]
+ tags = create_tags(song_attrs[3], genre, subgenre)
+ Song.new(song_attrs[0], song_attrs[1], genre, subgenre, tags)
+ end
+
+ def create_tags(tags_as_string, genre, subgenre)
+ tags = []
+ if (tags_as_string)
+ tags = tags_as_string.split(",").map(&:strip)
+ end
+ (tags + [genre, subgenre].select {|word| !word.nil?} .map(&:downcase)).uniq
+ end
+end