Ruby中过滤器的联合 [英] Union of filters in Ruby

查看:180
本文介绍了Ruby中过滤器的联合的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我设计了一个NumberSet类,它包含一个数组,我必须实现某些过滤器,我将其设计为类。代码是:

$ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $' ]
end
def each(&block)
@ arr.each do | member |
block.call(成员)
结束
结束
def<< (数字)
结束
def [](sito)
@ arr.select {| number | $ number
@ arr<<数字除非@ arr.include? sito.filter(number)}
end
end
$ b class过滤
attr_reader:过滤
def初始化&放大块
@filter = block
end
def filter number
@ filter.call(number)
end
end
$ b $ class SignFilter
def initialize (sign)
@sign = sign
end
def filter number
如果(@sign ==:negative&& number< 0)返回true
return如果(@sign ==:非负&& number> = 0)
返回true if(@sign ==:positive&& number> 0) sign ==:nonpositive&& number< = 0)
end
end
$ b $ class TypeFilter
def初始化(符号)
@签名= sign
end
def filter number
返回true if(@sign ==:complex&& number.is_a?(Complex)== true)
return true if (@sign ==:integer&& number.is_a?(Integer)== true)
返回true if(@sign ==:real&&(number.is_a?(Rational)==真
|| number.is_a?浮点数) == true))
end
end

一切正常,但我还必须定义& | 运算符,使它们像交集和联合一样工作,这意味着& 应该只能得到满足所有过滤器的数字,而至少能满足一个过滤器的 | 数字。

另外,语法

 数字[SignFilter.new非负)& Filter.new {| number | number.even? }] 

必须是有效的。

我如何定义他们,使他们正常工作?






要回答一些意见,我正在寻找一种方法让操作符& | 按我想要的方式工作。问题不在于如何编写语法,而是应该在 def end 之间的代码是什么。

解决方案

$ c $> class Filter
def initialize(& filter_block)
@filter_block = filter_block
end
def filter(number)
@ filter_block.call(number)
end
def&(other)
CompositeFilterAND.new(self,other)
end
def |(other)
CompositeFilterOR.new(self,其他)
结束
结束

类CompositeFilterAND
attr_accessor:left,:right

def初始化(左,右)
@left,@right = left,right
end

def filter(number)
@ left.filter(number)&& @ right.filter(数字)#这是魔术。
end
end

class CompositeFilterOR
attr_accessor:left,:right

def初始化(左,右)
@左,右=左,右
结束

def过滤器(数字)
@ left.filter(数字)|| @ right.filter(number)#这个。
end
end


I've designed a class NumberSet which contains an array on which I have to implement certain filters, which I've designed as classes. The code is:

class NumberSet
include Enumerable
 def initialize
    @arr=[]
 end
 def each (&block)
    @arr.each do |member|
        block.call (member)
    end
 end
 def << number
    @arr<<number unless  @arr.include?(number)
 end
 def [] (sito)
    @arr.select{|number| sito.filter(number)}
 end
end

class Filter
 attr_reader :filter
 def initialize &block
   @filter = block
 end
 def filter number
  @filter.call(number)
 end
end

class SignFilter
 def initialize(sign)
  @sign = sign
 end
 def filter number
  return true if(@sign==:negative && number<0)
  return true if(@sign==:positive && number>0)
  return true if(@sign==:nonnegative && number >= 0)
  return true if(@sign==:nonpositive && number <= 0)
 end
end

class TypeFilter
 def initialize(sign)
  @sign = sign
 end
 def filter number
  return true if (@sign==:complex && number.is_a?(Complex) == true)
  return true if (@sign==:integer && number.is_a?(Integer) == true)
  return true if (@sign==:real && (number.is_a?(Rational) == true 
  || number.is_a?Float)   == true))
 end
end

All works well, but I have to also define the & and | operators so they work like intersection and union, meaning that & should get only numbers that satisfy all filters and | numbers that satisfy at least one of the filters.

Also, the syntax

numbers[SignFilter.new(:non_negative) & Filter.new { |number| number.even? }]

must be valid.

How do I define them so they work correctly?


To answer some of the comments, I am looking for a way to make the operators &, | work the way I want them. The problem is not how to write the syntax, but rather what should the code between def and end be.

解决方案

How about something like this?

class Filter
  def initialize(&filter_block)
    @filter_block = filter_block
  end
  def filter(number)
    @filter_block.call(number)
  end
  def &(other)
    CompositeFilterAND.new(self, other)
  end
  def |(other)
    CompositeFilterOR.new(self, other)
  end
end

class CompositeFilterAND
  attr_accessor :left, :right

  def initialize(left, right)
    @left, @right = left, right
  end

  def filter(number)
    @left.filter(number) && @right.filter(number)  # This is the magic.
  end
end

class CompositeFilterOR
  attr_accessor :left, :right

  def initialize(left, right)
    @left, @right = left, right
  end

  def filter(number)
    @left.filter(number) || @right.filter(number)  # And this.
  end
end

这篇关于Ruby中过滤器的联合的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆