有没有一种简单的方法可以在Ruby中生成有序的夫妻
我想知道是否有类似于Range的东西但不是整数但是有序的夫妻(x,y) 。 我想知道是否有一种简单的方法可以做这样的事情:
((1,2)..(5,6)).each {|tmp| puts tmp} #=> (1,2) (3,4) (5,6)
编辑 :也许我不是100%明确在我的问题:)我会尝试以不同的方式问它。
如果我有这些夫妇: (3,4)和(5,6)我正在寻找一种方法来帮助我产生:
(3,4), (4,5), (5,6)
如果我不得不更好地开除它:如果夫妻是(x,y) – >
(x0,y0), ((x0+1),(y0+1)), ((x0+2), (y0+2)) and so on .
您可以将数组用作Range元素,例如:
> t = [1, 2]..[3, 4] => [1, 2]..[3, 4]
但是,它无法迭代,因为Array
类缺少succ
方法。
> t.each {|tmp| puts tmp} TypeError: can't iterate from Array from (irb):5:in `each' from (irb):5 from D:/Programmes/Ruby/bin/irb:12:in `'
因此,如果要允许使用数组进行迭代,请定义一个可以执行所需操作的Array#succ
方法:
class Array def succ self.map {|elem| elem + 1 } end end
这给你:
> t = [1, 2]..[3, 4] => [1, 2]..[3, 4] > t.each {|tmp| p tmp} [1, 2] [2, 3] [3, 4] => [1, 2]..[3, 4]
您可以使用Enumerable#each_slice
1.9.3-p327 :001 > (1..6).each_slice(2).to_a => [[1, 2], [3, 4], [5, 6]]
Ruby是一种面向对象的语言。 所以,如果你想用“有序的对象”做一些事情,那么你需要……好吧……一个OrderedCouple
对象。
class OrderedCouple < Struct.new(:x, :y) end OrderedCouple.new(3, 4) # => #
呃,看起来很难看:
class OrderedCouple def to_s; "(#{x}, #{y})" end alias_method :inspect, :to_s class << self; alias_method :[], :new end end OrderedCouple[3, 4] # => (3, 4)
Range
s用于两件事:检查包含和迭代。 为了将对象用作Range
的起点和终点,它必须响应<=>
。 如果你想迭代Range
,那么start对象必须响应succ
:
class OrderedCouple include Comparable def <=>(other) to_a <=> other.to_a end def to_a; [x, y] end def succ self.class[x.succ, y.succ] end end puts *OrderedCouple[1, 2]..OrderedCouple[5, 6] # (1, 2) # (2, 3) # (3, 4) # (4, 5) # (5, 6)
试试这个,
def tuples(x, y) return enum_for(:tuples, x, y) unless block_given? (0..Float::INFINITY).each { |i| yield [x + i, y + i] } end
然后,
tuples(1,7).take(4) # or tuples(1,7).take_while { |x, y| x <= 3 && y <= 9 }
两人都回归
[[1, 7], [2, 8], [3, 9]]