【问题标题】:how implement a function to iterate over if its passed a Range如果传递了一个范围,如何实现一个函数来迭代
【发布时间】:2020-07-05 10:14:18
【问题描述】:

我正在 Ruby 中创建自己的 .each 方法版本,但在实现它以用于 Range (1..10) 的输入时遇到问题。

module Enumerable
  # @return [Enumerable]
  def my_each
    return to_enum :my_each unless block_given?

    index = 0
    while index < size
      if is_a? Array
        yield self[index]
      elsif is_a? Hash
        yield keys[index], self[keys[index]]
      elsif is_a? Range
        yield self[index]
      end
      index += 1
    end
  end
end

如果通过了,我会尝试通过

r_list = (1..10)
r_list.my_each { |number| puts number }

输出将是

=> 
1
2
3
4
5
6
7
8
9
10

【问题讨论】:

  • each 不在Enumerable 中是有原因的:每个可枚举对象都应该提供自己的eachEnumerable 中的方法可以依靠它来准确地提供迭代对象的元素。也就是说...产生self.begin + index 应该没问题。
  • 对于@Amadan 的评论,请考虑Enumerable#map。还有一种方法Array#map 当然Array 包括Enumerable。我们发现[1].method(:map).owner #=&gt; Array[1].method(:map).super_method.owner #=&gt; Enumerable,所以arr.map { ... } 调用Array#map。包括Enumerable 的每个类C 都是一样的。 C 已经有一个方法 C#each 所以你的 Enumerable#each 不会被使用。结果是创建Enumerable 方法each 似乎毫无意义。

标签: ruby enumerable


【解决方案1】:

一种对该实现几乎没有改变的技术是将您的范围转换为数组。

module Enumerable
  def my_each
    return to_enum :my_each unless block_given?

    index = 0
    while index < size
      if is_a? Array
        yield self[index]
      elsif is_a? Hash
        yield keys[index], self[keys[index]]
      elsif is_a? Range
        yield to_a[index]
      end
      index += 1
    end
  end
end

r_list = (1..10)
puts r_list.my_each { |number| puts number }

结果:

1
2
3
4
5
6
7
8
9
10

【讨论】:

    猜你喜欢
    • 2011-01-28
    • 1970-01-01
    • 2020-07-04
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-10-14
    • 1970-01-01
    • 2019-12-17
    相关资源
    最近更新 更多