diff options
author | Alfonso Jiménez <me@alfie.cat> | 2018-11-20 11:51:08 +0100 |
---|---|---|
committer | Nobuyoshi Nakada <nobu@ruby-lang.org> | 2019-05-23 14:39:16 +0900 |
commit | 0acbdd1ed0d2302743525a5188cc5a0d6251680c (patch) | |
tree | c6e6787a1f706b36ea7b66094c0868a57864a09e /enum.c | |
parent | 1ccc2eeba08c370d84474357771f0bd7c5fe7f16 (diff) | |
download | ruby-0acbdd1ed0d2302743525a5188cc5a0d6251680c.tar.gz |
Adding Enumerable#filter_map
[Feature #15323]
Closes: https://github.com/ruby/ruby/pull/2017
Diffstat (limited to 'enum.c')
-rw-r--r-- | enum.c | 41 |
1 files changed, 41 insertions, 0 deletions
@@ -453,6 +453,46 @@ enum_find_all(VALUE obj) } static VALUE +filter_map_i(RB_BLOCK_CALL_FUNC_ARGLIST(i, ary)) +{ + i = rb_yield_values2(argc, argv); + + if (RTEST(i)) { + rb_ary_push(ary, i); + } + + return Qnil; +} + +/* + * call-seq: + * enum.filter_map { |obj| block } -> array + * enum.filter_map -> an_enumerator + * + * Returns a new array containing the truthy results (everything except + * +false+ or +nil+) of running the +block+ for every element in +enum+. + * + * If no block is given, an Enumerator is returned instead. + * + * + * (1..10).filter_map { |i| i * 2 if i.even? } #=> [4, 8, 12, 16, 20] + * + */ +static VALUE +enum_filter_map(VALUE obj) +{ + VALUE ary; + + RETURN_SIZED_ENUMERATOR(obj, 0, 0, enum_size); + + ary = rb_ary_new(); + rb_block_call(obj, id_each, 0, 0, filter_map_i, ary); + + return ary; +} + + +static VALUE reject_i(RB_BLOCK_CALL_FUNC_ARGLIST(i, ary)) { ENUM_WANT_SVALUE(); @@ -4108,6 +4148,7 @@ Init_Enumerable(void) rb_define_method(rb_mEnumerable, "find_all", enum_find_all, 0); rb_define_method(rb_mEnumerable, "select", enum_find_all, 0); rb_define_method(rb_mEnumerable, "filter", enum_find_all, 0); + rb_define_method(rb_mEnumerable, "filter_map", enum_filter_map, 0); rb_define_method(rb_mEnumerable, "reject", enum_reject, 0); rb_define_method(rb_mEnumerable, "collect", enum_collect, 0); rb_define_method(rb_mEnumerable, "map", enum_collect, 0); |