Решение на Втора задача от Йоан Карадимов

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

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

Резултати

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

Код

class Collection
def initialize(songs_as_string, artist_tags = {})
@pieces = songs_as_string.lines.map { |string| Piece.from_string string }
@pieces.each { |piece| piece.tags.push *artist_tags[piece.artist] }
end
def find(criteria = {})
@pieces
.select(&name_filter(criteria[:name]))
.select(&artist_filter(criteria[:artist]))
.select(&tag_filter(criteria[:tags]))
.select(&criteria[:filter])
end
private
NullFilter = lambda { |piece| true }
def name_filter(name)
return lambda { |piece| piece.name == name } if name
NullFilter
end
def artist_filter(artist)
return lambda { |piece| piece.artist == artist } if artist
NullFilter
end
def tag_filter(tags)
case tags
when [], nil
NullFilter
when Array
lambda do |piece|
first, *rest = *tags
tag_filter(first)[piece] and tag_filter(rest)[piece]
end
when /.*!$/ # ends in an exclaimation
lambda { |piece| not piece.tags.include?(tags[0...-1]) }
else
lambda { |piece| piece.tags.include? tags }
end
end
end
class Piece
FieldSeparator = '.'
SubfieldSeparator = ','
attr_reader :name, :artist, :genre, :subgenre, :tags
def initialize(name, artist, genres, tags = '')
@name = name.strip
@artist = artist.strip
@genre, @subgenre = Piece.split_field genres
add_tags tags
add_tags @genre.downcase
add_tags @subgenre.downcase if @subgenre
end
def add_tags(tags_as_string)
tags = Piece.split_field tags_as_string
@tags ||= []
@tags.push(*tags).uniq!
end
def self.from_string(string)
Piece.new *string.split(FieldSeparator)
end
private
def self.split_field(string_array)
string_array.split(SubfieldSeparator).map { |x| x.strip }
end
end

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

............

Finished in 0.54737 seconds
12 examples, 0 failures

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

Йоан обнови решението на 31.10.2011 16:27 (преди над 12 години)

+class Collection
+ def initialize(songs_as_string, artist_tags = {})
+ @pieces = songs_as_string.lines.map { |string| Piece.from_string string }
+ @pieces.each { |piece| piece.tags.push *artist_tags[piece.artist] }
+ end
+
+ def find(criteria = {})
+ @pieces
+ .select(&name_filter(criteria[:name]))
+ .select(&artist_filter(criteria[:artist]))
+ .select(&tag_filter(criteria[:tags]))
+ .select(&criteria[:filter])
+ end
+
+ private
+
+ NullFilter = lambda { |piece| true }
+
+ def name_filter(name)
+ return lambda { |piece| piece.name == name } if name
+ NullFilter
+ end
+
+ def artist_filter(artist)
+ return lambda { |piece| piece.artist == artist } if artist
+ NullFilter
+ end
+
+ def tag_filter(tags)
+ case tags
+ when [], nil
+ NullFilter
+ when Array
+ lambda do |piece|
+ first, *rest = *tags
+ tag_filter(first)[piece] and tag_filter(rest)[piece]
+ end
+ when /.*!$/ # ends in an exclaimation
+ lambda { |piece| not piece.tags.include?(tags[0...-1]) }
+ else
+ lambda { |piece| piece.tags.include? tags }
+ end
+ end
+end
+
+class Piece
+
+ FieldSeparator = '.'
+ SubfieldSeparator = ','
+
+ attr_reader :name, :artist, :genre, :subgenre, :tags
+
+ def initialize(name, artist, genres, tags = '')
+ @name = name.strip
+ @artist = artist.strip
+ @genre, @subgenre = Piece.split_field genres
+ add_tags tags
+ add_tags @genre.downcase
+ add_tags @subgenre.downcase if @subgenre
+ end
+
+ def add_tags(tags_as_string)
+ tags = Piece.split_field tags_as_string
+
+ @tags ||= []
+ @tags.push(*tags).uniq!
+ end
+
+ def self.from_string(string)
+ Piece.new *string.split(FieldSeparator)
+ end
+
+ private
+ def self.split_field(string_array)
+ string_array.split(SubfieldSeparator).map { |x| x.strip }
+ end
+
+end