Иван обнови решението на 26.10.2014 15:53 (преди около 10 години)
+class NumberSet
+ include Enumerable
+ def initialize(array = [])
+ @array = array
+ end
+
+ def each(&block)
+ @array.each(&block)
+ end
+
+ def <<(number)
+ @array << number unless @array.include? number
+ end
+
+ def size
+ @array.size
+ end
+
+ def empty?
+ @array.empty?
+ end
+
+ def [] (filter)
+ NumberSet.new(filter.apply_filter(@array))
+ end
+end
+
+class Filter
+
+ def initialize(&block)
+ @block = block
+ end
+
+ def apply_filter(array)
+ array.select(&@block)
+ end
+
+ def & (filter)
+ end
+
+ def | (filter)
+ end
+end
+
+
+
+class TypeFilter < Filter
+ def initialize(type)
+ @type = type
+ end
+
+ def check_type (number)
+ case @type
+ when :integer
+ number.is_a? Integer
+ when :complex
+ number.is_a? Complex
+ when :real
+ number.is_a? Rational or number.is_a? Float
+ end
+ end
+
+ def apply_filter(array)
+ filtered_array = []
+ array.each do |number|
+ if check_type(number)
+ filtered_array << number
+ end
+ end
+ filtered_array
+ end
+end
+
+
+class SignFilter < Filter
+ def initialize(sign)
+ @sign = sign
+ end
+
+ def check_sign (number)
+ if @sign == :positive
+ number > 0
+ elsif @sign == :non_positive
+ number <= 0
+ elsif @sign == :negative
+ number < 0
+ elsif @sign == :non_negative
+ number >= 0
+ end
+ end
+ def apply_filter(array)
+ filtered_array = []
+ array.each do |number|
+ if check_sign(number)
+ filtered_array << number
+ end
+ end
+ filtered_array
+ end
+end
- Моля погледни style guide-a, за да видиш къде следва или не следва да оставяш колко празни реда или space-а.
- Опитай се да измисляш имена, по-близки до домейна на проблема.
@array
като име описва само имплементационен детайл. Ако попиташ математик какво съдържа едно Множество от числа, най-вероятно няма да ти каже масив, а числа. Филтрите не филтрират по блок, а по някакво условие. - Не мисля, че това
apply_filter
да приема и връща масив е много добра идея. Ако утре решиш да пренапишешNumberSet
, така че да се представя чрезSet
, а неArray
ще трябва да го преобразуваш после. Би било по-добре да приема единично число и да казва, дали то удовлетворява или не дадения филтър. Също си написалapply_filter
доста процедурно. В Ruby се предпочита по-функционален подход, що се отнася до вътрешности. РазгледайEnumerable#select
. - Ако имаш проблеми с това как да имплементираш
Filter#|
иFilter#&
, а не просто не си имал време, попитай във форумите/прати email. - Когато сравняваш много пъти дали някаква променлива е равна на различни стойности използвай
case
, както си направил въвTypeFilter
.