Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/ruby/25.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
如何在Ruby中获取可枚举项的第n个元素_Ruby - Fatal编程技术网

如何在Ruby中获取可枚举项的第n个元素

如何在Ruby中获取可枚举项的第n个元素,ruby,Ruby,例如,要返回第10000个素数,我可以写: require 'prime' Prime.first(10000).last #=> 104729 但是创建一个巨大的中间数组,仅仅检索它的最后一个元素感觉有点麻烦 考虑到Ruby是一种如此优雅的语言,我本以为会出现以下情况: Prime.at(9999) #=> 104729 但在中没有可枚举的 上述解决方法是有意的还是有更直接的方法来获取可枚举的第n个元素 这个怎么样 Prime.to_enum.with_index(1){|e,

例如,要返回第10000个素数,我可以写:

require 'prime'
Prime.first(10000).last #=> 104729
但是创建一个巨大的中间数组,仅仅检索它的最后一个元素感觉有点麻烦

考虑到Ruby是一种如此优雅的语言,我本以为会出现以下情况:

Prime.at(9999) #=> 104729
但在中没有可枚举的

上述解决方法是有意的还是有更直接的方法来获取可枚举的第n个元素

这个怎么样

Prime.to_enum.with_index(1){|e, i| break e if i == 10000}
# => 104729
对于不懒惰的枚举数,您可能希望在枚举数上放置
lazy

基于,这里有一个更简洁的替代方法:

Prime.find.with_index(1) { |_, i| i == 10000 }
#=> 104729


我能想到的最接近于假设的
at
方法是
drop
,它跳过了指定数量的元素。它试图返回一个实际的数组,所以如果您使用无限序列,则需要将它与lazy组合,例如

Prime.lazy.drop(9999).first

请注意,
'0ab_1ab_2ab_3ab_4ab'.gsub(/。(?=ab)/).class#=>枚举器


需要进行一些改进,例如检查
n
是否为大于零的整数,以及改进异常处理,例如处理
self
不是枚举数但没有方法
的情况

这避免了中间数组,但不幸的是,它甚至更麻烦。你知道为什么没有像
Enumerable#at
这样的内置方法吗?可能是因为如果你只对某个特定的值感兴趣,那么应该有一个直接返回该值的方法,而不是作为枚举器。对于素数,我认为当你想要第n个时,会有更多的用例,而不是从头开始。因此,
Prime
类的设计没有达到应有的效果,或者受其内部算法的影响太大。我认为这是因为当我们使用
可枚举的
时,大多数时候我们实际上感兴趣的是对象的枚举,而不是某个特定索引处的对象,而且一个
可枚举的#at
并不难编写-参见@sawa示例。但这只是一种观点——我不知道这是否是正确的假设。@Stefan大多数时候可枚举对象实际上不是未绑定的,而是由一些有限的数据结构(例如
数组
,或
哈希
)支持的。在这里,直接从数据结构中获取第n个元素非常有效,而不必枚举列表,例如
my_array[10]
。如果您所拥有的只是一个(未绑定的)列表,那么您别无选择,只能获取所有元素并删除您不感兴趣的元素。最后,
Enumerable
模块提供的所有功能都是基于实现每个
方法以循环其任意元素的对象的。@HolgerJust这是正确的,我完全知道不能从
Enumerable
中跳过枚举。但这并不能解释为什么
Enumerable#at
缺失,是吗<代码>数组仍然可以在中提供<>代码>自己的(更快)的实现。考虑建议将< <代码>枚举的“< /代码>”添加到Ruby内核中。
Prime.lazy.drop(9999).first
module Enumerable
  def at(n)
    enum = is_a?(Enumerator) ? self : each
    (n-1).times { enum.next }
    enum.next
  end
end
(0..4).at(3)
  #=> 2 
{ a:1, b:2, c:3, d:4, e:5 }.at(3)
  #=> [:c, 3] 
'0ab_1ab_2ab_3ab_4ab'.gsub(/.(?=ab)/).at(3)
  #=> "2" 
require 'prime'; Prime.at(10000)
  #=> 104729 
e = 1.step; e.at(10)
  #=> 10 
[0,1,2,3,4].at(6)
  #=> nil 
'0ab_1ab_2ab_3ab_4ab'.gsub(/.(?=ab)/).at(6)
  #=> StopIteration (iteration reached an end)