Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/excel/24.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 Enumerable.collect,它返回一个可枚举值?_Ruby_Enumerable - Fatal编程技术网

等价于Ruby Enumerable.collect,它返回一个可枚举值?

等价于Ruby Enumerable.collect,它返回一个可枚举值?,ruby,enumerable,Ruby,Enumerable,在这段代码中,我创建了一个字符串数组1到10000: array_of_strings = (1..10000).collect {|i| String(i)} Ruby Core API是否提供了一种获取可枚举对象的方法,让我可以在同一个列表上枚举,根据需要生成字符串值,而不是生成字符串数组 下面是一个进一步的例子,希望能澄清我试图做的事情: def find_me_an_awesome_username awesome_names = (1..1000000).xform {|i| "

在这段代码中,我创建了一个字符串数组1到10000:

array_of_strings = (1..10000).collect {|i| String(i)}
Ruby Core API是否提供了一种获取可枚举对象的方法,让我可以在同一个列表上枚举,根据需要生成字符串值,而不是生成字符串数组

下面是一个进一步的例子,希望能澄清我试图做的事情:

def find_me_an_awesome_username
  awesome_names = (1..1000000).xform {|i| "hacker_" + String(i) }
  awesome_names.find {|n| not stackoverflow.userexists(n) }
end
其中,xform是我正在寻找的方法。 awesome_names是可枚举的,所以xform并不是创建一个100万元素的字符串数组,而是根据需要生成并返回hacker_N形式的字符串

顺便说一下,在C中它可能是这样的:

var awesomeNames = from i in Range(1, 1000000) select "hacker_" + i;
var name = awesomeNames.First((n) => !stackoverflow.UserExists(n));
一个解决方案

这里是对枚举器的扩展,它添加了一个xform方法。它返回另一个枚举数,该枚举数迭代原始枚举数的值,并对其应用转换

class Enumerator
  def xform(&block)
    Enumerator.new do |yielder|
      self.each do |val|
        yielder.yield block.call(val)
      end
    end
  end
end

# this prints out even numbers from 2 to 10:
(1..10).each.xform {|i| i*2}.each {|i| puts i}

每个方法都有一个列表:

(1..100000).each

听起来您需要一个枚举器对象,但不完全是这样

也就是说,枚举器对象是一个可用于按需调用next的对象,而不是执行整个循环的每个对象。许多人使用内部迭代器和外部迭代器的语言:每个迭代器都是内部的,枚举器是外部的。你开车

以下是枚举器的外观:

awesome_names = Enumerator.new do |y|
  number = 1
  loop do
    y.yield number
    number += 1
  end
end

puts awesome_names.next
puts awesome_names.next
puts awesome_names.next
puts awesome_names.next
这里有一个链接,更多地讨论如何在Ruby中懒洋洋地使用枚举器:

戴夫·托马斯(DaveThomas)的《Pickaxe编程Ruby》一书中也有一节介绍了这一点

class T < Range
  def each
    super { |i| yield String(i) }
  end
end

T.new(1,3).each { |s| p s }
$ ruby rsc.rb
"1"
"2"
"3"
下一步要做的事情是在调用枚举数时不使用块…

Ruby 2.0,它允许一个链式映射、选择等,并且只在结尾生成最终结果,使用to_a、first等。。。您可以在任何需要“backports/2.0.0/enumerable/lazy”的Ruby版本中使用它

否则,可以使用Enumerator.new{with_a_block}。它在Ruby 1.9中是新的,所以如果在Ruby 1.8.x中需要它,就需要“backports/1.9.1/enumerator/new”

根据您的示例,以下内容不会创建中间数组,只会构造所需的字符串:

require 'backports/1.9.1/enumerator/new'

def find_me_an_awesome_username
  awesome_names = Enumerator.new do |y|
    (1..1000000).each {|i| y.yield "hacker_" + String(i) }
  end
  awesome_names.find {|n| not stackoverflow.userexists(n) }
end
如果您愿意,您甚至可以将100000替换为1.0/0,即无穷大

要回答您的评论,如果您总是将您的值一一映射,您可以使用以下内容:

module Enumerable
  def lazy_each
    Enumerator.new do |yielder|
      each do |value|
        yielder.yield(yield value)
      end
    end
  end
end

awesome_names = (1..100000).lazy_each{|i| "hacker_#{i}"}

... 好的,现在开始搜索Ruby迭代,但代码只是在整数范围内迭代。它不会生成新的可枚举字符串。请试着设身处地为我想想:.1..100000.每人{j|i=j.to|s;做点什么j}还是你想做点不同的事?@anshul是的,我想做点不同的事。我想将生成可枚举值的代码与处理可枚举值的代码分开。TBH这不是唯一的方法,但在我看来,这当然会使代码更干净。谢谢。@mackenir,您可能应该按照建议公开一个each方法,该方法接受一个bock和一个Rangeeach的委托。将可枚举魔法保留在实现内部。谢谢。Hmmm.Find在找到匹配元素时肯定会停止枚举。您可以通过在很大范围内运行find来确认这一点,谓词“false”和“true”会立即返回。如果两者都在枚举所有内容,它们将同时返回。Re:enumeration with next,我试图找到“Enumeratable transformer”工具,以便编写更简洁的声明性代码,而手动枚举并不能真正实现这一点。也许答案就是实施它。所有的CRs都被移除了,这就不那么容易理解了。我的意思是,1..10000000000000000.find{I | true}很快,1..10000000000000000000000.find{I | false}很慢。意思是“查找”只是枚举,直到“查找”。有用的链接-我想我理解它,它帮助回答了这个问题。@marc,这看起来像!你知道我如何把这个模式变成一个更简洁的可重用方法,使用一个“可枚举的东西”和一个“转换器函数”吗?在本例中,“transformer函数”将是{i | hacker|uu+Stringi},而“可枚举的东西”将是1..100000或其他任何值。非常感谢。在我注意到你的更新之前,我根据你的回答和@Telemachus发布的链接更新了我的问题:再次感谢@mackenir:可枚举的转换函数是map。您应该能够将每个都更改为映射,并保持算法不变。@Chuck Enumerablemap是Enumerablecollect的同义词,因此它返回的是数组而不是枚举数。@mackenir:实际上,我读错了。为什么给出的方法不是你想要的?它接受一个transformer函数,并给出一个枚举数,该枚举数产生应用该转换的结果…应读取“2到20”
module Enumerable
  def lazy_each
    Enumerator.new do |yielder|
      each do |value|
        yielder.yield(yield value)
      end
    end
  end
end

awesome_names = (1..100000).lazy_each{|i| "hacker_#{i}"}