Project

General

Profile

Feature #11315 ยป array_xor.patch

0x0dea (D.E. Akers), 06/28/2015 02:22 PM

View differences:

array.c
4200 4200
    return ary3;
4201 4201
}
4202 4202

  
4203
/*
4204
 *  call-seq:
4205
 *     ary ^ other_ary     -> new_ary
4206
 *
4207
 *  Symmetric Difference --- Returns a new array containing the elements
4208
 *  which appear in either +ary+ or +other_ary+, but not both. The order
4209
 *  is preserved from the original array.
4210
 *
4211
 *  It compares elements using their #hash and #eql? methods for efficiency.
4212
 *
4213
 *     [1, 2, 3] ^ [2, 3, 4]    # => [1, 4]
4214
 *
4215
 *  If you need set-like behavior, see the library class Set.
4216
 */
4217

  
4218
static VALUE
4219
rb_ary_xor(VALUE ary1, VALUE ary2)
4220
{
4221
    VALUE hash, ary3;
4222
    st_data_t elt;
4223
    long i;
4224

  
4225
    ary2 = to_ary(ary2);
4226
    hash = ary_make_hash(ary1);
4227

  
4228
    for (i = 0; i < RARRAY_LEN(ary2); ++i) {
4229
    elt = (st_data_t)RARRAY_AREF(ary2, i);
4230
    if (st_lookup(RHASH_TBL_RAW(hash), elt, 0)) {
4231
        st_delete(RHASH_TBL_RAW(hash), &elt, 0);
4232
    }
4233
    else {
4234
        st_update(RHASH_TBL_RAW(hash), elt, ary_hash_orset, elt);
4235
    }
4236
    }
4237

  
4238
    ary3 = rb_hash_values(hash);
4239
    ary_recycle_hash(hash);
4240
    return ary3;
4241
}
4242

  
4203 4243
static int
4204 4244
push_value(st_data_t key, st_data_t val, st_data_t ary)
4205 4245
{
......
5862 5902
    rb_define_method(rb_cArray, "-", rb_ary_diff, 1);
5863 5903
    rb_define_method(rb_cArray, "&", rb_ary_and, 1);
5864 5904
    rb_define_method(rb_cArray, "|", rb_ary_or, 1);
5905
    rb_define_method(rb_cArray, "^", rb_ary_xor, 1);
5865 5906

  
5866 5907
    rb_define_method(rb_cArray, "uniq", rb_ary_uniq, 0);
5867 5908
    rb_define_method(rb_cArray, "uniq!", rb_ary_uniq_bang, 0);
test/ruby/test_array.rb
1724 1724
    assert_equal([obj1], [obj1]|[obj2])
1725 1725
  end
1726 1726

  
1727
  def test_XOR
1728
    assert_equal(@cls[],  @cls[]  ^ @cls[])
1729
    assert_equal(@cls[1], @cls[1] ^ @cls[])
1730
    assert_equal(@cls[1], @cls[]  ^ @cls[1])
1731
    assert_equal(@cls[],  @cls[1] ^ @cls[1])
1732

  
1733
    assert_equal(@cls[1,2], @cls[1] ^ @cls[2])
1734
    assert_equal(@cls[1,4], @cls[1,2,3] ^ @cls[2,3,4])
1735
  end
1736

  
1727 1737
  def test_combination
1728 1738
    assert_equal(@cls[[]], @cls[1,2,3,4].combination(0).to_a)
1729 1739
    assert_equal(@cls[[1],[2],[3],[4]], @cls[1,2,3,4].combination(1).to_a)