Skip to content

Commit c88354c

Browse files
committed
Add Array#find and Array#rfind
1 parent e232806 commit c88354c

File tree

2 files changed

+81
-0
lines changed

2 files changed

+81
-0
lines changed

core/array.rbs

Lines changed: 53 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2019,6 +2019,32 @@ class Array[unchecked out Elem] < Object
20192019
def filter!: () { (Elem item) -> boolish } -> self?
20202020
| () -> ::Enumerator[Elem, self?]
20212021

2022+
# <!--
2023+
# rdoc-file=array.c
2024+
# - find(if_none_proc = nil) {|element| ... } -> object or nil
2025+
# - find(if_none_proc = nil) -> enumerator
2026+
# -->
2027+
# Returns the first element for which the block returns a truthy value.
2028+
#
2029+
# With a block given, calls the block with successive elements of the array;
2030+
# returns the first element for which the block returns a truthy value:
2031+
#
2032+
# (0..9).find {|element| element > 2} # => 3
2033+
#
2034+
# If no such element is found, calls `if_none_proc` and returns its return
2035+
# value.
2036+
#
2037+
# (0..9).find(proc {false}) {|element| element > 12} # => false
2038+
# {foo: 0, bar: 1, baz: 2}.find {|key, value| key.start_with?('b') } # => [:bar, 1]
2039+
# {foo: 0, bar: 1, baz: 2}.find(proc {[]}) {|key, value| key.start_with?('c') } # => []
2040+
#
2041+
# With no block given, returns an Enumerator.
2042+
#
2043+
def find: () { (Elem) -> boolish } -> Elem?
2044+
| () -> ::Enumerator[Elem, Elem?]
2045+
| [T] (Enumerable::_NotFound[T] ifnone) { (Elem) -> boolish } -> (Elem | T)
2046+
| [T] (Enumerable::_NotFound[T] ifnone) -> ::Enumerator[Elem, Elem | T]
2047+
20222048
# <!--
20232049
# rdoc-file=array.c
20242050
# - find_index(object) -> integer or nil
@@ -2988,6 +3014,33 @@ class Array[unchecked out Elem] < Object
29883014
def reverse_each: () { (Elem item) -> void } -> self
29893015
| () -> ::Enumerator[Elem, self]
29903016

3017+
# <!--
3018+
# rdoc-file=array.c
3019+
# - rfind(if_none_proc = nil) {|element| ... } -> object or nil
3020+
# - rfind(if_none_proc = nil) -> enumerator
3021+
# -->
3022+
# Returns the last element for which the block returns a truthy value.
3023+
#
3024+
# With a block given, calls the block with successive elements of the array in
3025+
# reverse order; returns the last element for which the block returns a truthy
3026+
# value:
3027+
#
3028+
# (0..9).rfind {|element| element < 5} # => 4
3029+
#
3030+
# If no such element is found, calls `if_none_proc` and returns its return
3031+
# value.
3032+
#
3033+
# (0..9).rfind(proc {false}) {|element| element < -2} # => false
3034+
# {foo: 0, bar: 1, baz: 2}.rfind {|key, value| key.start_with?('b') } # => [:baz, 2]
3035+
# {foo: 0, bar: 1, baz: 2}.rfind(proc {[]}) {|key, value| key.start_with?('c') } # => []
3036+
#
3037+
# With no block given, returns an Enumerator.
3038+
#
3039+
def rfind: () { (Elem) -> boolish } -> Elem?
3040+
| () -> ::Enumerator[Elem, Elem?]
3041+
| [T] (Enumerable::_NotFound[T] ifnone) { (Elem) -> boolish } -> (Elem | T)
3042+
| [T] (Enumerable::_NotFound[T] ifnone) -> ::Enumerator[Elem, Elem | T]
3043+
29913044
# <!--
29923045
# rdoc-file=array.c
29933046
# - rindex(object) -> integer or nil

test/stdlib/Array_test.rb

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -411,6 +411,20 @@ def test_filter!
411411
[1,2,3], :filter!
412412
end
413413

414+
def test_find
415+
assert_send_type "() { (Integer) -> bool } -> Integer",
416+
[1,2,3], :find, &->(i) { i.odd? }
417+
assert_send_type "() { (Integer) -> bool } -> nil",
418+
[0,2], :find, &->(i) { i.odd? }
419+
assert_send_type "(Enumerable::_NotFound[String]) { (Integer) -> bool } -> String",
420+
[0,2], :find, -> { "" }, &->(i) { i.odd? }
421+
422+
assert_send_type "() -> Enumerator[Integer, Integer?]",
423+
[1,2,3], :find
424+
assert_send_type "(Enumerable::_NotFound[String]) -> Enumerator[Integer, Integer | String | nil]",
425+
[0,2], :find, -> { "" }
426+
end
427+
414428
def test_find_index
415429
assert_send_type "(Integer) -> Integer",
416430
[1,2,3], :find_index, 1
@@ -724,6 +738,20 @@ def test_reverse_each
724738
[2,3,4], :reverse_each
725739
end
726740

741+
def test_rfind
742+
assert_send_type "() { (Integer) -> bool } -> Integer",
743+
[1,2,3], :rfind, &->(i) { i.odd? }
744+
assert_send_type "() { (Integer) -> bool } -> nil",
745+
[0,2], :rfind, &->(i) { i.odd? }
746+
assert_send_type "(Enumerable::_NotFound[String]) { (Integer) -> bool } -> String",
747+
[0,2], :rfind, -> { "" }, &->(i) { i.odd? }
748+
749+
assert_send_type "() -> Enumerator[Integer, Integer?]",
750+
[1,2,3], :rfind
751+
assert_send_type "(Enumerable::_NotFound[String]) -> Enumerator[Integer, Integer | String | nil]",
752+
[0,2], :rfind, -> { "" }
753+
end
754+
727755
def test_rindex
728756
assert_send_type "(Integer) -> Integer",
729757
[1,2,3], :rindex, 1

0 commit comments

Comments
 (0)