【问题标题】:How can I modify my ruby method so it takes in a block of code as well?如何修改我的 ruby​​ 方法,使其也包含一段代码?
【发布时间】:2017-11-22 17:58:53
【问题描述】:

我有一个名为 myFilter 的方法,它接受一个数组,并过滤​​掉不符合要求的元素。

例如。

arr = [4,5,8,9,1,3,6]

answer = myfilter(arr) {|i| i>=5}

此运行将返回一个包含元素 5、8、9、6 的数组,因为它们都大于或等于 5。

我将如何执行此操作?算法很简单,但我不明白我们如何在这种情况下接受。

谢谢。

【问题讨论】:

  • 你写了你有这样的方法,但毕竟你似乎没有这样的方法。
  • 你能告诉我们你的方法 myFilter 中的代码吗?
  • 你知道myfilter(arr) { ... } 等价于arr.select { ... },不是吗?
  • 如果您想让我们告诉您如何修改您的方法,您应该向我们展示您的方法。

标签: ruby methods yield


【解决方案1】:

你可以的

def my_filter(arr, &block)
  arr.select(&block)
end

然后调用

my_filter([1, 2, 3]) { |e| e > 2 }
=> [3]

但是您可以直接使用块调用select :)

【讨论】:

    【解决方案2】:

    我想当然地认为您不想使用 select 方法或类似方法,但您想了解块的工作原理。

    def my_filter(arr)
      if block_given?
        result = []
        arr.each { |element| result.push(element) if yield element } # here you use the block passed to this method and execute it with the current element using yield
        result
      else
        arr
      end
    end
    

    【讨论】:

    • 最好的做法是提供return enum_for(:myfilter, *args) unless block_given? 以便能够在没有块的情况下调用此方法(惰性)。
    【解决方案3】:

    惯用的方式是:

    def my_filter(arr)
      return enum_for(:my_filter, arr) unless block_given?
    
      arr.each_with_object([]) do |e, acc|
        acc << e if yield e
      end
    end
    

    更多关于Enumerator::Lazy#enum_for的信息。

    【讨论】:

      猜你喜欢
      • 2020-08-18
      • 1970-01-01
      • 1970-01-01
      • 2019-06-13
      • 2021-07-20
      • 1970-01-01
      • 1970-01-01
      • 2016-08-03
      • 1970-01-01
      相关资源
      最近更新 更多