Ruby:修改范围

时间:2014-12-16 14:44:32

标签: ruby

我正在尝试向Range类添加方法。目标是检查范围中是否包含整数,如果不包括则包括它。存储Range一些最小值和最大值会很有用。

所以我想到了以下内容:

class Range   
  def include!(n)
    if n < self.begin
      self = n..self.end
    elsif n > self.end
      self = self.begin..n
    end   
  end 
end

r = Range.new(500, 500)
100.times do
  r.include!(rand(1000))
end

但我收到Can't change the value of self错误。

这是唯一的解决方案:

class Range
  def include(n)
    if n < self.begin
      n..self.end
    elsif n > self.end
      self.begin..n
    else
      self
    end
  end
end

r = Range.new(500, 500)
100.times do
  r = r.include(rand(1000))
end

1 个答案:

答案 0 :(得分:1)

范围本身是不可变的,创建后无法更改其属性。但是,正如您所发现的那样,通过创建新范围而不是修改现有范围,仍然可以实现您想要的效果。我可能会这样做:

module RangeAdder
  def +(value)
    return self if value.nil?
    return self + value.min + value.max if value.is_a? Range
    return value.reduce(self, :+) if value.is_a? Enumerable

    new_begin       = [self.begin, value].min
    new_end         = [self.end, value].max
    new_exclude_end = value > self.end ? false : self.exclude_end?
    Range.new(new_begin, new_end, new_exclude_end)
  end
end

class Range
  include RangeAdder
end

然后:

r = 500..500
r += Array.new(100) { rand(1000) }
#=> 15..982

或者,如果您真正想要的是从数组中获取最小值和最大值,则可以使用:

a = Array.new(100) { rand(1000) }
r = Range.new(*a.minmax)
#=> 11..996