我有一个数组a = [1, 2, 3, 4, 5]
如果我的数组中有一个元素,我可以通过该数组中的下一个元素通过 a[0].next
有没有可以使用的方法来查找上一个元素 a[1].previous
或a[1].before
,因此结果为
#=> 1
我围绕着谷歌搜索,似乎大多数其他类似的问题都涉及一个我不想做的循环。我还检查了枚举者的红宝石文档&枚举,似乎找不到一个。
>> a = [1, 2, 3, 4, 5] #=> [1, 2, 3, 4, 5]
>> a[0].next #=> 2
>> a[2].previous
NoMethodError: undefined method `previous' for 3:Fixnum
from (irb):14
from /Users/Lois/.rvm/rubies/ruby-2.3.1/bin/irb:11:in `<main>'
>> a[2].before
NoMethodError: undefined method `before' for 3:Fixnum
from (irb):15
from /Users/Lois/.rvm/rubies/ruby-2.3.1/bin/irb:11:in `<main>'
预先感谢!
如果您有数组:
a = [ 1, 2, 3, 4 ]
然后调用a[1]
将返回对象2
,并且该值没有什么特别的,一旦您检索到上下文就没有上下文。因此,在其上调用next
将始终产生3
,因为这是Integer#next
所做的。
为了浏览该数组,您需要某种迭代器,例如枚举:
e = a.each
现在您可以做您想做的事:
e.next
# => 1
e.next
# => 2
请注意,此界面并不像您期望的那样灵活。您可以致电next
提前,或者rewind
返回开始,但是没有previous
。Ruby没有其他语言术语为双向迭代器,但是如果您感到勇敢,您也许可以扩展此类的功能。
我总是最终会搅拌这样的东西。
当然,这种方法不仅限于Array
S-我不想使其成为EnumerableScanner
,但是,由于某些枚举保持了复杂的状态(想想斐波那契序列)。
class ArrayScanner
attr_reader :index, :array
def initialize(array)
@array = array
@index = 0
end
def next
raise StopIteration unless next?
@array[@index += 1]
end
def peek
raise StopIteration unless next?
@array[@index + 1]
end
def next?
@index + 1 != @array.size
end
def prev
raise StopIteration unless prev?
@array[@index -= 1]
end
def peek_prev
raise StopIteration unless prev?
@array[@index - 1]
end
def prev?
@index - 1 >= 0
end
def eof?
!next?
end
def bof?
!prev?
end
def current
@array[@index]
end
def current=(new_value)
@array[@index] = new_value
end
def size
@array.size
end
def pos
@index
end
def rewind
@index = 0
end
end
a = ArrayScanner.new [1, 2, 3, 4, 5]
a.current #=> 1
a.next #=> 2
a.current #=> 2
a.prev #=> 1
a.prev? #=> false
a.bof? #=> true
4.times { a.next }
a.eof? #=> true
a.current #=> 5
水晶语具有类似的方法,它是迭代器模块。
a = [1, 2, 3, 4, 5]
i = 0
a[i] #=> 1
a[i.next] #=> 2
a[i.pred] #=> 5
i = 1
s = 1
a[i] #=> 2
a[i + s] #=> 3
a[i - s] #=> 1