Project

General

Profile

Feature #12247 ยป delete_multi.patch

usa (Usaku NAKAMURA), 04/03/2016 09:45 AM

View differences:

array.c (working copy)
2948 2948
    }
2949 2949
}
2950 2950

  
2951
static VALUE
2952
rb_ary_delete_internal(VALUE ary, VALUE item, int *deleted)
2953
{
2954
    VALUE v = item;
2955
    long i1, i2;
2956

  
2957
    for (i1 = i2 = 0; i1 < RARRAY_LEN(ary); i1++) {
2958
	VALUE e = RARRAY_AREF(ary, i1);
2959

  
2960
	if (rb_equal(e, item)) {
2961
	    v = e;
2962
	    continue;
2963
	}
2964
	if (i1 != i2) {
2965
	    rb_ary_store(ary, i2, e);
2966
	}
2967
	i2++;
2968
    }
2969

  
2970
    if (RARRAY_LEN(ary) == i2) {
2971
	if (deleted) *deleted = 0;
2972
	if (rb_block_given_p()) {
2973
	    return rb_yield(item);
2974
	}
2975
	return Qnil;
2976
    }
2977

  
2978
    if (deleted) *deleted = 1;
2979
    ary_resize_smaller(ary, i2);
2980

  
2981
    return v;
2982
}
2983

  
2984
VALUE
2985
rb_ary_delete(VALUE ary, VALUE item)
2986
{
2987
    return rb_ary_delete_internal(ary, item, NULL);
2988
}
2989

  
2951 2990
/*
2952 2991
 *  call-seq:
2953 2992
 *     ary.delete(obj)            -> item or nil
2954 2993
 *     ary.delete(obj) { block }  -> item or result of block
2994
 *     ary.delete(...)            -> [items]
2995
 *     ary.delete(...) { block }  -> [items] or [results of block]
2955 2996
 *
2956 2997
 *  Deletes all items from +self+ that are equal to +obj+.
2957 2998
 *
......
2961 3002
 *  the item is not found.  (To remove +nil+ elements and get an informative
2962 3003
 *  return value, use Array#compact!)
2963 3004
 *
3005
 *  If passed multiple arguments, delete them from +self+ and returns the
3006
 *  deleted items as an Array.  In this case, if no item is deleted, returns
3007
 *  empty Array.
3008
 *
2964 3009
 *     a = [ "a", "b", "b", "b", "c" ]
2965 3010
 *     a.delete("b")                   #=> "b"
2966 3011
 *     a                               #=> ["a", "c"]
2967 3012
 *     a.delete("z")                   #=> nil
2968 3013
 *     a.delete("z") { "not found" }   #=> "not found"
3014
 *     a.delete("a", "c")              #=> ["a", "c"]
3015
 *     a                               #=> []
3016
 *     a.delete("a", "c")              #=> []
2969 3017
 */
2970 3018

  
2971
VALUE
2972
rb_ary_delete(VALUE ary, VALUE item)
3019
static VALUE
3020
rb_ary_delete_m(int argc, VALUE *argv, VALUE ary)
2973 3021
{
2974
    VALUE v = item;
2975
    long i1, i2;
3022
    switch (argc) {
3023
      case 0:
3024
	return Qnil;
3025
      case 1:
3026
	return rb_ary_delete_internal(ary, argv[0], NULL);
3027
      default:
3028
	{
3029
	    VALUE r = rb_ary_new();
3030
	    VALUE e;
3031
	    int i;
2976 3032

  
2977
    for (i1 = i2 = 0; i1 < RARRAY_LEN(ary); i1++) {
2978
	VALUE e = RARRAY_AREF(ary, i1);
2979

  
2980
	if (rb_equal(e, item)) {
2981
	    v = e;
2982
	    continue;
3033
	    for (i = 0; i < argc; i++) {
3034
		int deleted;
3035
		e = rb_ary_delete_internal(ary, argv[i], &deleted);
3036
		if (deleted || rb_block_given_p()) {
3037
		    rb_ary_push(r, e);
2983 3038
	}
2984
	if (i1 != i2) {
2985
	    rb_ary_store(ary, i2, e);
2986 3039
	}
2987
	i2++;
3040
	    return r;
2988 3041
    }
2989
    if (RARRAY_LEN(ary) == i2) {
2990
	if (rb_block_given_p()) {
2991
	    return rb_yield(item);
2992 3042
	}
2993
	return Qnil;
2994 3043
    }
2995 3044

  
2996
    ary_resize_smaller(ary, i2);
2997

  
2998
    return v;
2999
}
3000

  
3001 3045
void
3002 3046
rb_ary_delete_same(VALUE ary, VALUE item)
3003 3047
{
......
5951 5995
    rb_define_method(rb_cArray, "select!", rb_ary_select_bang, 0);
5952 5996
    rb_define_method(rb_cArray, "keep_if", rb_ary_keep_if, 0);
5953 5997
    rb_define_method(rb_cArray, "values_at", rb_ary_values_at, -1);
5954
    rb_define_method(rb_cArray, "delete", rb_ary_delete, 1);
5998
    rb_define_method(rb_cArray, "delete", rb_ary_delete_m, -1);
5955 5999
    rb_define_method(rb_cArray, "delete_at", rb_ary_delete_at_m, 1);
5956 6000
    rb_define_method(rb_cArray, "delete_if", rb_ary_delete_if, 0);
5957 6001
    rb_define_method(rb_cArray, "reject", rb_ary_reject, 0);
test/ruby/test_array.rb (working copy)
626 626
    a = @cls[1, o, o2, 2]
627 627
    assert_equal(o2, a.delete(42))
628 628
    assert_equal([1, 2], a)
629

  
630
    a = @cls[*('cab'..'cat').to_a]
631
    assert_equal(['cab', 'car'], a.delete('cab', 'car'))
632
    assert_equal(@cls[*('cac'..'caq').to_a] + @cls[*('cas'..'cat').to_a], a)
633

  
634
    a = @cls[*('cab'..'cat').to_a]
635
    assert_equal(['cap'], a.delete('cap', 'caz'))
636
    assert_equal(@cls[*('cab'..'cao').to_a] + @cls[*('caq'..'cat').to_a], a)
637

  
638
    a = @cls[*('cab'..'cat').to_a]
639
    assert_equal(nil, a.delete())
640
    assert_equal(@cls[*('cab'..'cat').to_a], a)
641

  
642
    a = @cls[*('cab'..'cat').to_a]
643
    assert_equal(['cap', 99], a.delete('cap', 'caz') { 99 })
644
    assert_equal(@cls[*('cab'..'cao').to_a] + @cls[*('caq'..'cat').to_a], a)
645

  
646
    a = @cls[*('cab'..'cat').to_a]
647
    assert_equal(['cap', nil], a.delete('cap', 'caz') { nil })
648
    assert_equal(@cls[*('cab'..'cao').to_a] + @cls[*('caq'..'cat').to_a], a)
629 649
  end
630 650

  
631 651
  def test_delete_at