Илиян обнови решението на 30.10.2012 02:01 (преди около 12 години)
+class Song
+ attr_accessor :name, :artist, :album
+
+ def initialize(args)
+ @name = args[0]
+ @artist = args[1]
+ @album = args[2]
+ end
+end
+
+class Criteria
+ attr_accessor :value
+
+ def initialize(&block)
+ @value = block
+ end
+
+ def self.name(arg)
+ Criteria.new { |song| song.name == arg }
+ end
+
+ def self.artist(arg)
+ Criteria.new { |song| song.artist == arg }
+ end
+
+ def self.album(arg)
+ Criteria.new { |song| song.album == arg }
+ end
+
+ def &(other)
+ Criteria.new { |song| @value.call(song) and other.value.call(song) }
+ end
+
+ def |(other)
+ Criteria.new { |song| @value.call(song) or other.value.call(song) }
+ end
+
+ def !
+ Criteria.new { |song| not @value.call(song) }
+ end
+end
+
+class Collection
+ include Enumerable
+ attr_accessor :storage
+
+ def initialize(data)
+ @storage = data
+ end
+
+ def each
+ @storage.each { |item| yield item }
+ end
+
+ def self.parse(data)
+ songList = []
+ data.split("\n\n").each { |song| songList << Song.new(song.split("\n")) }
+ Collection.new songList
+ end
+
+ def filter(conditions)
+ Collection.new @storage.select { |song| conditions.value.call(song) }
+ end
+
+ def adjoin(filtered)
+ Collection.new (@storage + filtered.storage).uniq
+ end
+
+ def artists
+ @storage.collect { |song| song.artist }.uniq
+ end
+
+ def albums
+ @storage.collect { |song| song.album }.uniq
+ end
+
+ def names
+ @storage.collect { |song| song.name }.uniq
+ end
+end