Решение на Втора задача от Филарета Йорданова

Обратно към всички решения

Към профила на Филарета Йорданова

Резултати

  • 6 точки от тестове
  • 0 бонус точки
  • 6 точки общо
  • 11 успешни тест(а)
  • 0 неуспешни тест(а)

Код

class Song
attr_accessor :name, :artist, :album
def initialize(name, artist, album)
@name = name
@artist = artist
@album = album
end
def Song.parse_song(song)
song_attributes = song.split(/\n/)
Song.new song_attributes[0],song_attributes[1],song_attributes[2]
end
def name
@name
end
def artist
@artist
end
def album
@album
end
end
class Collection
include Enumerable
def each
@songs.each do |song|
yield song
end
end
attr_accessor :songs
def initialize(songs)
@songs = songs
end
def Collection.parse(text)
songs = text.split(/\n\n/).map{ |item| Song.parse_song(item) }
Collection.new songs
end
def names
map{ |song| song.name }.uniq
end
def artists
map{ |song| song.artist }.uniq
end
def albums
map{ |song| song.album }.uniq
end
def filter(filter_by)
new_songs = select{ |song| filter_by.matches? song }
Collection.new new_songs
end
def adjoin(collection)
new_songs = songs | collection.songs
Collection.new new_songs
end
end
class Criteria
attr_accessor :criteria
def initialize(&criteria)
@criteria = criteria
end
def Criteria.name(name)
Criteria.new { |item| item.name == name }
end
def Criteria.artist(artist)
Criteria.new { |item| item.artist == artist }
end
def Criteria.album(album)
Criteria.new { |item| item.album == album }
end
def |(other)
Criteria.new { |song| criteria.call(song) | other.criteria.call(song) }
end
def &(other)
Criteria.new { |song| criteria.call(song) & other.criteria.call(song) }
end
def !
Criteria.new { |song| !criteria.call(song) }
end
def matches?(song)
criteria.call(song)
end
end

Лог от изпълнението

...........

Finished in 0.01046 seconds
11 examples, 0 failures

История (3 версии и 1 коментар)

Филарета обнови решението на 28.10.2012 20:01 (преди над 11 години)

+class Song
+ include Enumerable
+
+ def each
+ yield @name
+ yield @artist
+ yield @album
+ end
+
+ attr_accessor :name, :artist, :album
+
+ def initialize(name, artist, album)
+ @name = name
+ @artist = artist
+ @album = album
+ end
+
+ def Song.parse_song(song)
+ song_attributes = song.split(/\n/)
+ Song.new song_attributes[0],song_attributes[1],song_attributes[2]
+ end
+
+ def name
+ @name
+ end
+
+ def artist
+ @artist
+ end
+
+ def album
+ @album
+ end
+end
+
+class Collection
+ include Enumerable
+
+ def each
+ @songs.each do |song|
+ yield song
+ end
+ end
+
+ attr_accessor :songs
+
+ def initialize(songs)
+ @songs = songs
+ end
+
+ def Collection.parse(text)
+ songs = text.split(/\n\n/).map{ |item| Song.parse_song(item) }
+ Collection.new songs
+ end
+
+ def names
+ @songs.map{ |song| song.name }.uniq
+ end
+
+ def artists
+ @songs.map{ |song| song.artist }.uniq
+ end
+
+ def albums
+ @songs.map{ |song| song.album }.uniq
+ end
+
+ def filter(filter_by)
+ new_songs = select(&filter_by.criteria).map do |i|
+ Song.new(i.name,i.artist,i.album)
+ end
+ Collection.new new_songs
+ end
+
+ def adjoin(collection)
+ songs = @songs | collection.songs
+ Collection.new songs
+ end
+end
+
+class Criteria
+ attr_accessor :criteria
+
+ def initialize(criteria)
+ @criteria = criteria
+ end
+
+ def Criteria.name(name)
+ Criteria.new proc { |item| item.name == name }
+ end
+
+ def Criteria.artist(artist)
+ Criteria.new proc { |item| item.artist == artist }
+ end
+
+ def Criteria.album(album)
+ Criteria.new proc { |item| item.album == album }
+ end
+
+ def |(other)
+ Criteria.new proc { |song| criteria.call(song) | other.criteria.call(song) }
+ end
+
+ def &(other)
+ Criteria.new proc { |song| criteria.call(song) & other.criteria.call(song) }
+ end
+
+ def !(other)
+ Criteria.new proc { |song| criteria.call(song) - other.criteria.call(song) }
+ end
+end

Добре, но има няколко неща.

  • Защо Song е Enumerable? Какъв е смисъла от това?
  • select(&filter_by.criteria) не ми харесва. Защо не го направиш с select { |song| filter_by.matches? song } пробвай да видиш, че ще стане по-добре.
  • Вместо да подаваш proc на конструктора на Criteria, можеш да подадеш блок. Пак ще стане по-добре.
  • Защо във filter правиш копие на песните? По принцип са immutable и няма нужда. А дори да имаше, това става с #dup и #clone, а не "на ръка"

Филарета обнови решението на 30.10.2012 00:14 (преди над 11 години)

class Song
- include Enumerable
- def each
- yield @name
- yield @artist
- yield @album
- end
-
attr_accessor :name, :artist, :album
def initialize(name, artist, album)
@name = name
@artist = artist
@album = album
end
def Song.parse_song(song)
song_attributes = song.split(/\n/)
Song.new song_attributes[0],song_attributes[1],song_attributes[2]
end
def name
@name
end
def artist
@artist
end
def album
@album
end
end
class Collection
include Enumerable
def each
@songs.each do |song|
yield song
end
end
attr_accessor :songs
def initialize(songs)
@songs = songs
end
def Collection.parse(text)
songs = text.split(/\n\n/).map{ |item| Song.parse_song(item) }
Collection.new songs
end
def names
- @songs.map{ |song| song.name }.uniq
+ map{ |song| song.name }.uniq
end
def artists
- @songs.map{ |song| song.artist }.uniq
+ map{ |song| song.artist }.uniq
end
def albums
- @songs.map{ |song| song.album }.uniq
+ map{ |song| song.album }.uniq
end
def filter(filter_by)
- new_songs = select(&filter_by.criteria).map do |i|
- Song.new(i.name,i.artist,i.album)
- end
+ new_songs = select{ |song| filter_by.matches? song}
Collection.new new_songs
end
def adjoin(collection)
- songs = @songs | collection.songs
- Collection.new songs
+ new_songs = songs | collection.songs
+ Collection.new new_songs
end
end
class Criteria
attr_accessor :criteria
- def initialize(criteria)
+ def initialize(&criteria)
@criteria = criteria
end
def Criteria.name(name)
- Criteria.new proc { |item| item.name == name }
+ Criteria.new { |item| item.name == name }
end
def Criteria.artist(artist)
- Criteria.new proc { |item| item.artist == artist }
+ Criteria.new { |item| item.artist == artist }
end
def Criteria.album(album)
- Criteria.new proc { |item| item.album == album }
+ Criteria.new { |item| item.album == album }
end
def |(other)
- Criteria.new proc { |song| criteria.call(song) | other.criteria.call(song) }
+ Criteria.new { |song| criteria.call(song) | other.criteria.call(song) }
end
def &(other)
- Criteria.new proc { |song| criteria.call(song) & other.criteria.call(song) }
+ Criteria.new { |song| criteria.call(song) & other.criteria.call(song) }
end
- def !(other)
- Criteria.new proc { |song| criteria.call(song) - other.criteria.call(song) }
+ def !
+ Criteria.new { |song| !criteria.call(song) }
+ end
+
+ def matches?(song)
+ criteria.call(song)
end
end

Филарета обнови решението на 30.10.2012 00:16 (преди над 11 години)

class Song
attr_accessor :name, :artist, :album
def initialize(name, artist, album)
@name = name
@artist = artist
@album = album
end
def Song.parse_song(song)
song_attributes = song.split(/\n/)
Song.new song_attributes[0],song_attributes[1],song_attributes[2]
end
def name
@name
end
def artist
@artist
end
def album
@album
end
end
class Collection
include Enumerable
def each
@songs.each do |song|
yield song
end
end
attr_accessor :songs
def initialize(songs)
@songs = songs
end
def Collection.parse(text)
songs = text.split(/\n\n/).map{ |item| Song.parse_song(item) }
Collection.new songs
end
def names
map{ |song| song.name }.uniq
end
def artists
map{ |song| song.artist }.uniq
end
def albums
map{ |song| song.album }.uniq
end
def filter(filter_by)
- new_songs = select{ |song| filter_by.matches? song}
+ new_songs = select{ |song| filter_by.matches? song }
Collection.new new_songs
end
def adjoin(collection)
new_songs = songs | collection.songs
Collection.new new_songs
end
end
class Criteria
attr_accessor :criteria
def initialize(&criteria)
@criteria = criteria
end
def Criteria.name(name)
Criteria.new { |item| item.name == name }
end
def Criteria.artist(artist)
Criteria.new { |item| item.artist == artist }
end
def Criteria.album(album)
Criteria.new { |item| item.album == album }
end
def |(other)
Criteria.new { |song| criteria.call(song) | other.criteria.call(song) }
end
def &(other)
Criteria.new { |song| criteria.call(song) & other.criteria.call(song) }
end
def !
Criteria.new { |song| !criteria.call(song) }
end
def matches?(song)
criteria.call(song)
end
end