From bb78c2cbc9698541857c8e85a57fd1583d070ae7 Mon Sep 17 00:00:00 2001 From: leviongit Date: Sat, 13 Apr 2024 07:41:00 +0200 Subject: [PATCH] reimplement `Array#delete` with a helper method --- mrblib/array.rb | 26 ++------------------------ src/array.c | 43 +++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 45 insertions(+), 24 deletions(-) diff --git a/mrblib/array.rb b/mrblib/array.rb index 066f1d3a0..1ae20489e 100644 --- a/mrblib/array.rb +++ b/mrblib/array.rb @@ -191,31 +191,9 @@ class Array # # Delete element with index +key+ def delete(key, &block) - ret = key - i = 0 - j = 0 len = self.length - while i < len - elem = self[i] - - if key == elem - ret = elem - i += 1 - next - end - - self[j] = elem if i != j - - i += 1 - j += 1 - end - - if i == j - return block.call if block - return nil - end - - self.replace(self[0...j]) + ret = self.__delete(key) + return block.call() if len == self.length ret end diff --git a/src/array.c b/src/array.c index 7e2d03c65..cbea95dbe 100644 --- a/src/array.c +++ b/src/array.c @@ -1397,6 +1397,48 @@ mrb_ary_svalue(mrb_state *mrb, mrb_value ary) } } +static mrb_value +mrb_ary_delete(mrb_state *mrb, mrb_value self) +{ + struct RArray *ary = RARRAY(self); + mrb_value *val_ptr = ARY_PTR(ary); + size_t len = ARY_LEN(ary); + mrb_bool modified = FALSE; + + mrb_value obj = mrb_get_arg1(mrb); + mrb_value ret = obj; + + size_t i = 0; + size_t j = 0; + for (; i < len; ++i) { + mrb_value elem = val_ptr[i]; + + if (mrb_equal(mrb, elem, obj)) { + ret = elem; + continue; + } + + if (i != j) { + if (!modified) { + ary_modify(mrb, ary); + val_ptr = ARY_PTR(ary); + modified = TRUE; + } + val_ptr[j] = elem; + } + + ++j; + } + + if (i == j) { + return mrb_nil_value(); + } + + ARY_SET_LEN(ary, j); + + return ret; +} + void mrb_init_array(mrb_state *mrb) { @@ -1438,5 +1480,6 @@ mrb_init_array(mrb_state *mrb) mrb_define_method_id(mrb, a, MRB_SYM(__ary_eq), mrb_ary_eq, MRB_ARGS_REQ(1)); mrb_define_method_id(mrb, a, MRB_SYM(__ary_cmp), mrb_ary_cmp, MRB_ARGS_REQ(1)); mrb_define_method_id(mrb, a, MRB_SYM(__ary_index), mrb_ary_index_m, MRB_ARGS_REQ(1)); /* kept for mruby-array-ext */ + mrb_define_method_id(mrb, a, MRB_SYM(__delete), mrb_ary_delete, MRB_ARGS_REQ(1)); mrb_define_method_id(mrb, a, MRB_SYM(__svalue), mrb_ary_svalue, MRB_ARGS_NONE()); }