Николай обнови решението на 31.10.2012 11:01 (преди около 12 години)
+class Song
+ attr_accessor :name, :artist, :album
+
+ def initialize( name, artist, album )
+ @name, @artist,@album = name, artist,album
+ end
+
+end
+
+class Collection
+ include Enumerable
+
+ def initialize( list_of_songs = [] )
+ @list_of_songs = list_of_songs
+ end
+
+ def each
+ @list_of_songs.each{ |song| yield song }
+ end
+
+ def Collection.parse( text )
+ parsed_songs = []
+ text.split("\n").each_slice(4) do |song|
+ parsed_songs << Song.new(song[0], song[1], song[2])
+ end
+ Collection.new( parsed_songs )
+ end
+
+ def artist
+ @list_of_songs.group_by{ |song| song.artist }.keys
+ end
+
+ def albums
+ @list_of_songs.group_by{ |song| song.album }.keys
+ end
+
+ def names
+ @list_of_songs.group_by{ |song| song.name }.keys
+ end
+
+ def filter( creteria )
+ Collection.new( @list_of_songs.select{ |song| creteria.call(song) } )
+ end
+
+ def adjoin( collection )
+ list_of_songs = @list_of_songs
+ collection.each{ |song| list_of_songs << song }
+ Collection.new( list_of_songs )
+ end
+
+end
+
+class Criteria
+
+ def initialize( filter )
+ @filter = filter
+ end
+
+ def Criteria.name( name )
+ Criteria.new( Proc.new{ |song| song.name == name } )
+ end
+
+ def Criteria.artist( artist )
+ Criteria.new( Proc.new{ |song| song.artist == artist } )
+ end
+
+ def Criteria.album( album )
+ Criteria.new( Proc.new{ |album| song.album == album } )
+ end
+
+ def !
+ Criteria.new( Proc.new{ |song| not call(song) } )
+ end
+
+ def &(other)
+ Criteria.new( Proc.new{ |song| call(song) and other.call(song) } )
+ end
+
+ def |( other )
+ Criteria.new( Proc.new{ |song| call(song) or other.call(song) } )
+ end
+
+ def call( song )
+ @filter.call( song )
+ end
+end