Method: Array#uniq!

Defined in:
array.c

#uniq!self? #uniq! {|element| ... } ⇒ self?

Removes duplicate elements from self, the first occurrence always being retained; returns self if any elements removed, nil otherwise.

With no block given, identifies and removes elements using method eql? to compare elements:

a = [0, 0, 1, 1, 2, 2]
a.uniq! # => [0, 1, 2]
a.uniq! # => nil

With a block given, calls the block for each element; identifies and omits “duplicate” elements using method eql? to compare block return values; that is, an element is a duplicate if its block return value is the same as that of a previous element:

a = ['a', 'aa', 'aaa', 'b', 'bb', 'bbb']
a.uniq! {|element| element.size } # => ["a", "aa", "aaa"]
a.uniq! {|element| element.size } # => nil

Related: see Methods for Deleting.

Overloads:

  • #uniq!self?

    Returns:

    • (self, nil)
  • #uniq! {|element| ... } ⇒ self?

    Yields:

    • (element)

    Returns:

    • (self, nil)


6303
6304
6305
6306
6307
6308
6309
6310
6311
6312
6313
6314
6315
6316
6317
6318
6319
6320
6321
6322
6323
6324
6325
6326
6327
6328
6329
6330
6331
# File 'array.c', line 6303

static VALUE
rb_ary_uniq_bang(VALUE ary)
{
    VALUE hash;
    long hash_size;

    rb_ary_modify_check(ary);
    if (RARRAY_LEN(ary) <= 1)
        return Qnil;
    if (rb_block_given_p())
        hash = ary_make_hash_by(ary);
    else
        hash = ary_make_hash(ary);

    hash_size = RHASH_SIZE(hash);
    if (RARRAY_LEN(ary) == hash_size) {
        return Qnil;
    }
    rb_ary_modify_check(ary);
    ARY_SET_LEN(ary, 0);
    if (ARY_SHARED_P(ary)) {
        rb_ary_unshare(ary);
        FL_SET_EMBED(ary);
    }
    ary_resize_capa(ary, hash_size);
    rb_hash_foreach(hash, push_value, ary);

    return ary;
}