【问题标题】:Is there any way to use more than one attribute/method with ampersand colon operator in Ruby?有没有办法在 Ruby 中使用多个属性/方法和 & 冒号运算符?
【发布时间】:2018-10-16 19:43:24
【问题描述】:

应该是这样的:给定一个 foo 对象数组,其属性为 bar,该属性还具有一个名为 baz 的属性:

foos.each(&:bar.baz)

我可以很容易地用foos.each(&:bar) 获得所有bars,但是baz 属性(或者其他许多属性)我不能,因为它给了我错误: TypeError: wrong argument type String (expected Proc)

【问题讨论】:

  • 根据您的示例,我假设您想使用单个&符号运算符,但是您将绿色者授予执行常规操作的答案,将两个计算链接起来,每个计算都使用&符号操作员。请澄清。
  • 不,我不想要一个 & 符号,只是一种链接 barbaz 的调用的方法。但是你为我回答工作,作为被接受的人。谢谢

标签: ruby


【解决方案1】:

使用.map:

foos.map(&:bar).each(&:baz)

这会将您的foo 项数组转换为bar 项数组,从而允许您调用.each

【讨论】:

  • 这不能回答问题;这是一种解决方法。
  • @CarySwoveland 问题是 “在 Ruby 中,有没有办法在 & 和冒号运算符中使用多个属性/方法?” 这个答案显示了你是如何做到的。
  • 我已经要求 OP 进行澄清。顺便说一句,您为什么认为需要foos.map(&:bar).each(&:baz),而不是foos.each(&:bar).map(&:baz)foos.each(&:bar).each(&:baz)?我意识到each 返回了它的接收者,但它也可能有副作用。
【解决方案2】:

Array#each 返回其接收者,因此它可能不是您正在寻找的最佳示例。假设我们有

arr = [['a', 'b'], ['c', 'd']]

想要

arr.map(&:first).map(&:upcase)
  #=> ["A", "C"]

使用一个 & 符号可以写

arr.map(&Proc.new { |e| e.first.upcase })
  #=> ["A", "C"]

& 将 proc 转换为块,导致

arr.map { |e| e.first.upcase }

被执行。

【讨论】:

  • 很高兴有你在这里!感谢您分享您的知识。
  • 此外,我们可以尽情享受每个人的乐趣 HereJ-uby 的疯狂
  • 这是另一种有趣的方式来做我想做的事。除此之外,您和 Sergio 的解释让我更好地理解了 & 运算符。由于 GoBusto 的回答也解决了我的问题,我会保留它。谢谢
【解决方案3】:

是否可以使用 & 冒号运算符

没有。主要是因为没有“和号冒号运算符”之类的东西。这个

foos.each(&:bar)

是写这个的更短的方式

sym = :bar
foos.each(&sym)

另请参阅其他答案。

【讨论】:

    【解决方案4】:

    最好的选择是只使用常规的块语法:

    foos.each { |foo| foo.bar.baz }
    

    如果您仍想使用&:sym 类型的语法,例如因为方法名称是动态的,您可以查看Xf gem。它使您能够:

    foos.each(&Xf.pipe(:bar, :baz))
    

    您可以简单地通过借用pipe 方法来复制功能而不包括gem:

    def pipe(*fns)
      Proc.new do |target|
        new_value = target
        fns.each { |fn| new_value = fn.to_proc.call(new_value) }
        new_value
      end
    end
    
    require 'ostruct'
    # openstruct used to emulate objects that would respond to .foo.bar
    foos = []
    foos << OpenStruct.new(foo: OpenStruct.new(bar: 'hello'))
    foos << OpenStruct.new(foo: OpenStruct.new(bar: 'world'))
    foos.each(&pipe(:foo, :bar))
    

    【讨论】:

    • 为什么是map 而不是each?根据问题中给出的信息,我们可以断定哪个是正确的吗?
    • 无理由,各换一个。
    猜你喜欢
    • 2023-04-08
    • 1970-01-01
    • 2013-01-23
    • 2020-04-20
    • 1970-01-01
    • 2020-01-26
    • 2021-12-23
    • 2017-07-08
    相关资源
    最近更新 更多