Ruby Array find_first đối tượng?


135

Tôi có thiếu một cái gì đó trong tài liệu Array không? Tôi có một mảng chứa tối đa một đối tượng thỏa mãn một tiêu chí nhất định. Tôi muốn tìm thấy đối tượng đó một cách hiệu quả. Ý tưởng tốt nhất tôi có từ các tài liệu là thế này:

candidates = my_array.select { |e| e.satisfies_condition? }
found_it = candidates.first if !candidates.empty?

Nhưng tôi không hài lòng vì hai lý do:

  1. Điều đó selectkhiến tôi đi qua toàn bộ mảng, mặc dù chúng tôi có thể đã bảo lãnh sau cú đánh đầu tiên.
  2. Tôi cần một dòng mã (có điều kiện) để làm phẳng các ứng cử viên.

Cả hai hoạt động đều lãng phí với sự biết trước rằng có 0 hoặc 1 đối tượng thỏa mãn.

Những gì tôi muốn là một cái gì đó như:

array.find_first(block)

trong đó trả về nil hoặc đối tượng đầu tiên mà khối đánh giá là true, kết thúc giao dịch tại đối tượng đó.

Tôi phải tự viết cái này chứ? Tất cả những phương thức tuyệt vời khác trong Array khiến tôi nghĩ rằng nó ở đó và tôi chỉ không thấy nó.

Câu trả lời:


201

Hoặc tôi không hiểu câu hỏi của bạn, hoặc Vô số # find là điều bạn đang tìm kiếm.


32
Không có vấn đề gì, tôi cũng thường thấy khó chịu khi tài liệu ruby ​​không liệt kê các phương thức của tất cả các lớp và mô-đun được kế thừa hoặc bao gồm.
Mladen Jablanović

4
Thông tin thêm: [1,2,3,5,2].find { |n| puts n; n == 2 } Lặp lại dừng khi tìm thấy phần tử đầu tiên phù hợp.
rajuGT

97

sử dụng detectphương thức mảng nếu bạn muốn trả về giá trị đầu tiên trong đó khối trả về true

[1,2,3,11,34].detect(&:even?) #=> 2

OR

[1,2,3,11,34].detect{|i| i.even?} #=> 2

Nếu bạn muốn trả về tất cả các giá trị trong đó khối trả về true thì sử dụng select

[1,2,3,11,34].select(&:even?)  #=> [2, 34]

5
.detectchính xác là những gì tôi cần. Nhưng sự khác biệt với .findsau đó là gì?
Augustin Riedinger

13
@AugustinRiedinger không có sự khác biệt, cả hai đều giống nhau. detectchỉ là bí danh của find ruby-doc.org/core-2.1.2/Enumerable.html#method-i-find
Sandip Ransing

để có sự nhất quán, tôi thích làm theo Hướng dẫn về Phong cách Ruby , được ưa thích tìm thấy
Paul van Leeuwen

20

Đoán bạn vừa bỏ lỡ phương thức tìm trong tài liệu:

my_array.find {|e| e.satisfies_condition? }

8
Hoặc nếu bạn thích chơi gôn mã,my_array.find(&:satisfies_condition?)
Andrew Grimm

14

Bạn có cần các đối tượng bản thân hay bạn chỉ cần biết nếu có một đối tượng mà thỏa mãn. Nếu trước đây thì có: sử dụng find:

found_object = my_array.find { |e| e.satisfies_condition? }

nếu không bạn có thể sử dụng any?

found_it = my_array.any?  { |e| e.satisfies_condition? }

Cái sau sẽ bảo lãnh với "true" khi nó tìm thấy một cái thỏa mãn điều kiện. Cái trước sẽ làm tương tự, nhưng trả lại đối tượng.

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.