@@ -2088,6 +2088,99 @@ rb_ary_fetch(int argc, VALUE *argv, VALUE ary)
20882088 return RARRAY_AREF (ary , idx );
20892089}
20902090
2091+ /*
2092+ * call-seq:
2093+ * find(if_none_proc = nil) {|element| ... } -> object or nil
2094+ * find(if_none_proc = nil) -> enumerator
2095+ *
2096+ * Returns the first element for which the block returns a truthy value.
2097+ *
2098+ * With a block given, calls the block with successive elements of the array;
2099+ * returns the first element for which the block returns a truthy value:
2100+ *
2101+ * (0..9).find {|element| element > 2} # => 3
2102+ *
2103+ * If no such element is found, calls +if_none_proc+ and returns its return value.
2104+ *
2105+ * (0..9).find(proc {false}) {|element| element > 12} # => false
2106+ * {foo: 0, bar: 1, baz: 2}.find {|key, value| key.start_with?('b') } # => [:bar, 1]
2107+ * {foo: 0, bar: 1, baz: 2}.find(proc {[]}) {|key, value| key.start_with?('c') } # => []
2108+ *
2109+ * With no block given, returns an Enumerator.
2110+ *
2111+ */
2112+
2113+ static VALUE
2114+ rb_ary_find (int argc , VALUE * argv , VALUE ary )
2115+ {
2116+ VALUE if_none ;
2117+ long idx ;
2118+
2119+ RETURN_ENUMERATOR (ary , argc , argv );
2120+ if_none = rb_check_arity (argc , 0 , 1 ) ? argv [0 ] : Qnil ;
2121+
2122+ for (idx = 0 ; idx < RARRAY_LEN (ary ); idx ++ ) {
2123+ VALUE elem = RARRAY_AREF (ary , idx );
2124+ if (RTEST (rb_yield (elem ))) {
2125+ return elem ;
2126+ }
2127+ }
2128+
2129+ if (!NIL_P (if_none )) {
2130+ return rb_funcallv (if_none , idCall , 0 , 0 );
2131+ }
2132+ return Qnil ;
2133+ }
2134+
2135+ /*
2136+ * call-seq:
2137+ * rfind(if_none_proc = nil) {|element| ... } -> object or nil
2138+ * rfind(if_none_proc = nil) -> enumerator
2139+ *
2140+ * Returns the last element for which the block returns a truthy value.
2141+ *
2142+ * With a block given, calls the block with successive elements of the array in
2143+ * reverse order; returns the last element for which the block returns a truthy
2144+ * value:
2145+ *
2146+ * (0..9).rfind {|element| element < 5} # => 4
2147+ *
2148+ * If no such element is found, calls +if_none_proc+ and returns its return value.
2149+ *
2150+ * (0..9).rfind(proc {false}) {|element| element < -2} # => false
2151+ * {foo: 0, bar: 1, baz: 2}.rfind {|key, value| key.start_with?('b') } # => [:baz, 2]
2152+ * {foo: 0, bar: 1, baz: 2}.rfind(proc {[]}) {|key, value| key.start_with?('c') } # => []
2153+ *
2154+ * With no block given, returns an Enumerator.
2155+ *
2156+ */
2157+
2158+ static VALUE
2159+ rb_ary_rfind (int argc , VALUE * argv , VALUE ary )
2160+ {
2161+ VALUE if_none ;
2162+ long len , idx ;
2163+
2164+ RETURN_ENUMERATOR (ary , argc , argv );
2165+ if_none = rb_check_arity (argc , 0 , 1 ) ? argv [0 ] : Qnil ;
2166+
2167+ idx = RARRAY_LEN (ary );
2168+ while (idx -- ) {
2169+ VALUE elem = RARRAY_AREF (ary , idx );
2170+ if (RTEST (rb_yield (elem ))) {
2171+ return elem ;
2172+ }
2173+
2174+ len = RARRAY_LEN (ary );
2175+ idx = (idx >= len ) ? len : idx ;
2176+ }
2177+
2178+ if (!NIL_P (if_none )) {
2179+ return rb_funcallv (if_none , idCall , 0 , 0 );
2180+ }
2181+ return Qnil ;
2182+ }
2183+
20912184/*
20922185 * call-seq:
20932186 * find_index(object) -> integer or nil
@@ -8816,6 +8909,8 @@ Init_Array(void)
88168909 rb_define_method (rb_cArray , "length" , rb_ary_length , 0 );
88178910 rb_define_method (rb_cArray , "size" , rb_ary_length , 0 );
88188911 rb_define_method (rb_cArray , "empty?" , rb_ary_empty_p , 0 );
8912+ rb_define_method (rb_cArray , "find" , rb_ary_find , -1 );
8913+ rb_define_method (rb_cArray , "rfind" , rb_ary_rfind , -1 );
88198914 rb_define_method (rb_cArray , "find_index" , rb_ary_index , -1 );
88208915 rb_define_method (rb_cArray , "index" , rb_ary_index , -1 );
88218916 rb_define_method (rb_cArray , "rindex" , rb_ary_rindex , -1 );
0 commit comments