Ruby 中是否有一种方法与 find 相反?

发布于 2024-11-04 07:46:46 字数 277 浏览 4 评论 0 原文

a, b, c = 0, 1, 2
[a, b, c].find(&:zero?) # => 0

是否有任何方法可以找到块返回 false 的第一个元素?

[a, b, c].the_method(&:zero?) # => 1

换句话说,它的行为方式与以下内容相同:

[a, b, c].reject(&:zero?).first
a, b, c = 0, 1, 2
[a, b, c].find(&:zero?) # => 0

Is there any method that finds the first element for which the block returns false?

[a, b, c].the_method(&:zero?) # => 1

In other words, it would behave the same way as:

[a, b, c].reject(&:zero?).first

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

相守太难 2024-11-11 07:46:51

不是,但是你可以用干净的方式创建一个:

a = [0,2,1,0,3]

module Enumerable
  def first_not(&block)
    find{ |x| !block[x] }
  end
end

p a.first_not(&:zero?)
#=> 2

...或者可怕的方式-有趣的黑客方式:

class Proc
  def !
    proc{ |o,*a| !self[o,*a] }
  end
end

p a.find(&!(:zero?.to_proc))
#=> 2

...或者简洁但非常危险的方式:

class Symbol
  def !
    proc{ |o,*a| !o.send(self,*a) }
  end
end

p a.find(&!:zero?)
#=> 2

但我建议跳过棘手的 Symbol#to_proc 用法并说出你想要的内容:

p a.find{ |i| !i.zero? }
#=> 2

There is not, but you could create one either the clean-ish way:

a = [0,2,1,0,3]

module Enumerable
  def first_not(&block)
    find{ |x| !block[x] }
  end
end

p a.first_not(&:zero?)
#=> 2

...or the horribly-amusing hack way:

class Proc
  def !
    proc{ |o,*a| !self[o,*a] }
  end
end

p a.find(&!(:zero?.to_proc))
#=> 2

...or the terse-but-terribly-dangerous way:

class Symbol
  def !
    proc{ |o,*a| !o.send(self,*a) }
  end
end

p a.find(&!:zero?)
#=> 2

But I'd advocate just skipping the tricky Symbol#to_proc usage and saying what you want:

p a.find{ |i| !i.zero? }
#=> 2
时光倒影 2024-11-11 07:46:51

如果您使用的是 Ruby 2.0,则可以执行 lazy.reject(&:zero?).first ,而不会因遍历整个数组而造成性能损失。

If you're using Ruby 2.0, you may be able to do lazy.reject(&:zero?).first without the performance penalty of going through the full array.

把梦留给海 2024-11-11 07:46:51

据我所知,没有一个标准方法可以做到这一点(假设 find_all 和拒绝相互引用,但 find 不引用任何内容)。如果你经常需要它(特别是如果拒绝太慢)你可以自己编写

module Enumerable

  def first_reject(&block)
    find {|a| not (block.call(a)) }
  end

end

As far as I can tell there is not a standard method to do this (given that find_all and reject reference each other, but find does not reference anything). If you need it frequently (especially if the reject is too slow) you can write your own

module Enumerable

  def first_reject(&block)
    find {|a| not (block.call(a)) }
  end

end
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文