123456789_123456789_123456789_123456789_123456789_

Class: Set

Relationships & Source Files
Namespace Children
Classes:
Super Chains via Extension / Inclusion / Inheritance
Instance Chain:
self, ::Enumerable
Inherits: Object
Defined in: set.c,
set.c

Overview

Copyright © 2002-2024 Akinori MUSHA <knu@iDaemons.org>

Documentation by Akinori MUSHA and Gavin Sinclair.

All rights reserved. You can redistribute and/or modify it under the same terms as ::Ruby.

The Set class implements a collection of unordered values with no duplicates. It is a hybrid of Array’s intuitive inter-operation facilities and Hash’s fast lookup.

Set is easy to use with ::Enumerable objects (implementing #each). Most of the initializer methods and binary operators accept generic ::Enumerable objects besides sets and arrays. An Enumerable object can be converted to Set using the #to_set method.

Set uses a data structure similar to ::Hash for storage, except that it only has keys and no values.

  • Equality of elements is determined according to Object#eql? and Object#hash. Use Set#compare_by_identity to make a set compare its elements by their identity.

  • Set assumes that the identity of each element does not change while it is stored. Modifying an element of a set will render the set to an unreliable state.

  • When a string is to be stored, a frozen copy of the string is stored instead unless the original string is already frozen.

Comparison

The comparison operators <, >, #<=, and #>= are implemented as shorthand for the proper_,subset?,superset? methods. The #<=> operator reflects this order, or returns nil for sets that both have distinct elements ({x, y} vs. {x, z} for example).

Example

s1 = Set[1, 2]                        #=> #<Set: {1, 2}>
s2 = [1, 2].to_set                    #=> #<Set: {1, 2}>
s1 == s2                              #=> true
s1.add("foo")                         #=> #<Set: {1, 2, "foo"}>
s1.merge([2, 6])                      #=> #<Set: {1, 2, "foo", 6}>
s1.subset?(s2)                        #=> false
s2.subset?(s1)                        #=> true

Contact

  • Akinori MUSHA <knu@iDaemons.org> (current maintainer)

What’s Here

First, what's elsewhere. \Class \Set:
  • Inherits from class Object.

  • Includes module Enumerable, which provides dozens of additional methods.

In particular, class Set does not have many methods of its own for fetching or for iterating. Instead, it relies on those in Enumerable.

Here, class Set provides methods that are useful for:

  • Creating an Array

  • {Array@Methods+for+Creating+a+Set Creating a }

  • Operations

  • Comparing

  • Querying

  • Assigning

  • Deleting

  • Converting

  • Iterating

  • And more.…

Methods for Creating a Set

  • .[]: Returns a new set containing the given objects.

  • .new: Returns a new set containing either the given objects (if no block given) or the return values from the called block (if a block given).

Methods for Set Operations

  • #| (aliased as #union and #+): Returns a new set containing all elements from self and all elements from a given enumerable (no duplicates).

  • #& (aliased as #intersection): Returns a new set containing all elements common to self and a given enumerable.

  • #- (aliased as #difference): Returns a copy of self with all elements in a given enumerable removed.

  • #^: Returns a new set containing all elements from self and a given enumerable except those common to both.

Methods for Comparing

  • #<=>: Returns -1, 0, or 1 as self is less than, equal to, or greater than a given object.

  • #==: Returns whether self and a given enumerable are equal, as determined by Object#eql?.

  • #compare_by_identity?: Returns whether the set considers only identity when comparing elements.

Methods for Querying

  • #length (aliased as #size): Returns the count of elements.

  • #empty?: Returns whether the set has no elements.

  • #include? (aliased as #member? and #===): Returns whether a given object is an element in the set.

  • #subset? (aliased as #<=): Returns whether a given object is a subset of the set.

  • #proper_subset? (aliased as #<): Returns whether a given enumerable is a proper subset of the set.

  • #superset? (aliased as #>=): Returns whether a given enumerable is a superset of the set.

  • #proper_superset? (aliased as #>): Returns whether a given enumerable is a proper superset of the set.

  • #disjoint?: Returns true if the set and a given enumerable have no common elements, false otherwise.

  • #intersect?: Returns true if the set and a given enumerable: have any common elements, false otherwise.

  • #compare_by_identity?: Returns whether the set considers only identity when comparing elements.

Methods for Assigning

  • #add (aliased as #<<): Adds a given object to the set; returns self.

  • #add?: If the given object is not an element in the set, adds it and returns self; otherwise, returns nil.

  • #merge: Merges the elements of each given enumerable object to the set; returns self.

  • #replace: Replaces the contents of the set with the contents of a given enumerable.

Methods for Deleting

  • #clear: Removes all elements in the set; returns self.

  • #delete: Removes a given object from the set; returns self.

  • #delete?: If the given object is an element in the set, removes it and returns self; otherwise, returns nil.

  • #subtract: Removes each given object from the set; returns self.

  • #delete_if - Removes elements specified by a given block.

  • #select! (aliased as #filter!): Removes elements not specified by a given block.

  • #keep_if: Removes elements not specified by a given block.

  • #reject! Removes elements specified by a given block.

Methods for Converting

  • #classify: Returns a hash that classifies the elements, as determined by the given block.

  • #collect! (aliased as #map!): Replaces each element with a block return-value.

  • #divide: Returns a hash that classifies the elements, as determined by the given block; differs from #classify in that the block may accept either one or two arguments.

  • #flatten: Returns a new set that is a recursive flattening of self.

  • #flatten!: Replaces each nested set in self with the elements from that set.

  • #inspect (aliased as #to_s): Returns a string displaying the elements.

  • #join: Returns a string containing all elements, converted to strings as needed, and joined by the given record separator.

  • #to_a: Returns an array containing all set elements.

  • #to_set: Returns self if given no arguments and no block; with a block given, returns a new set consisting of block return values.

Methods for Iterating

  • #each: Calls the block with each successive element; returns self.

Other Methods

  • #reset: Resets the internal state; useful if an object has been modified while an element in the set.

Class Method Summary

Instance Attribute Summary

Instance Method Summary

::Enumerable - Included

#all?

Returns whether every element meets a given criterion.

#any?

Returns whether any element meets a given criterion.

#chain

Returns an enumerator object generated from this enumerator and given enumerables.

#chunk

Each element in the returned enumerator is a 2-element array consisting of:

#chunk_while

Creates an enumerator for each chunked elements.

#collect

Alias for Enumerable#map.

#collect_concat
#compact

Returns an array of all non-nil elements:

#count

Returns the count of elements, based on an argument or block criterion, if given.

#cycle

When called with positive integer argument n and a block, calls the block with each element, then does so again, until it has done so n times; returns nil:

#detect

Alias for Enumerable#find.

#drop

For positive integer n, returns an array containing all but the first n elements:

#drop_while

Calls the block with successive elements as long as the block returns a truthy value; returns an array of all elements after that point:

#each_cons

Calls the block with each successive overlapped n-tuple of elements; returns self:

#each_entry

Calls the given block with each element, converting multiple values from yield to an array; returns self:

#each_slice

Calls the block with each successive disjoint n-tuple of elements; returns self:

#each_with_index

Invoke self.each with *args.

#each_with_object

Calls the block once for each element, passing both the element and the given object:

#entries

Alias for Enumerable#to_a.

#filter

Returns an array containing elements selected by the block.

#filter_map

Returns an array containing truthy elements returned by the block.

#find

Returns the first element for which the block returns a truthy value.

#find_all
#find_index

Returns the index of the first element that meets a specified criterion, or nil if no such element is found.

#first

Returns the first element or elements.

#flat_map

Returns an array of flattened objects returned by the block.

#grep

Returns an array of objects based elements of self that match the given pattern.

#grep_v

Returns an array of objects based on elements of self that don’t match the given pattern.

#group_by

With a block given returns a hash:

#include?
#inject

Returns the result of applying a reducer to an initial value and the first element of the ::Enumerable.

#lazy

Returns an ::Enumerator::Lazy, which redefines most ::Enumerable methods to postpone enumeration and enumerate values only on an as-needed basis.

#map

Returns an array of objects returned by the block.

#max

Returns the element with the maximum element according to a given criterion.

#max_by

Returns the elements for which the block returns the maximum values.

#member?

Returns whether for any element object == element:

#min

Returns the element with the minimum element according to a given criterion.

#min_by

Returns the elements for which the block returns the minimum values.

#minmax

Returns a 2-element array containing the minimum and maximum elements according to a given criterion.

#minmax_by

Returns a 2-element array containing the elements for which the block returns minimum and maximum values:

#none?

Returns whether no element meets a given criterion.

#one?

Returns whether exactly one element meets a given criterion.

#partition

With a block given, returns an array of two arrays:

#reduce
#reject

Returns an array of objects rejected by the block.

#reverse_each

With a block given, calls the block with each element, but in reverse order; returns self:

#select
#slice_after

Creates an enumerator for each chunked elements.

#slice_before

With argument pattern, returns an enumerator that uses the pattern to partition elements into arrays (“slices”).

#slice_when

Creates an enumerator for each chunked elements.

#sort

Returns an array containing the sorted elements of self.

#sort_by

With a block given, returns an array of elements of self, sorted according to the value returned by the block for each element.

#sum

With no block given, returns the sum of initial_value and the elements:

#take

For non-negative integer n, returns the first n elements:

#take_while

Calls the block with successive elements as long as the block returns a truthy value; returns an array of all elements up to that point:

#tally

When argument #hash is not given, returns a new hash whose keys are the distinct elements in self; each integer value is the count of occurrences of each element:

#to_a

Returns an array containing the items in self:

#to_h

When self consists of 2-element arrays, returns a hash each of whose entries is the key-value pair formed from one of those arrays:

#to_set

Makes a set from the enumerable object with given arguments.

#uniq

With no block, returns a new array containing only unique elements; the array has no two elements e0 and e1 such that e0.eql?(e1):

#zip

With no block given, returns a new array new_array of size self.size whose elements are arrays.

Constructor Details

.newSet .new(enum) ⇒ Set .new(enum) {|elem| ... } ⇒ Set

Creates a new set containing the elements of the given enumerable object.

If a block is given, the elements of enum are preprocessed by the given block.

Set.new([1, 2])                       #=> #<Set: {1, 2}>
Set.new([1, 2, 1])                    #=> #<Set: {1, 2}>
Set.new([1, 'c', :s])                 #=> #<Set: {1, "c", :s}>
Set.new(1..5)                         #=> #<Set: {1, 2, 3, 4, 5}>
Set.new([1, 2, 3]) { |x| x * x }      #=> #<Set: {1, 4, 9}>
[ GitHub ]

  
# File 'set.c', line 485

static VALUE
set_i_initialize(int argc, VALUE *argv, VALUE set)
{
    if (RBASIC(set)->flags & RSET_INITIALIZED) {
        rb_raise(rb_eRuntimeError, "cannot reinitialize set");
    }
    RBASIC(set)->flags |= RSET_INITIALIZED;

    VALUE other;
    rb_check_arity(argc, 0, 1);

    if (argc > 0 && (other = argv[0]) != Qnil) {
        if (RB_TYPE_P(other, T_ARRAY)) {
            long len = RARRAY_LEN(other);
            if (RARRAY_LEN(other) != 0) {
                set_table *into = RSET_TABLE(set);
                VALUE key;
                int block_given = rb_block_given_p();
                RARRAY_PTR_USE(other, ptr, {
                    for(; len > 0; len--, ptr++) {
                        key = *ptr;
                        if (block_given) key = rb_yield(key);
                        set_table_insert_wb(into, set, key, NULL);
                    }
                });
            }
        }
        else {
            rb_block_call(other, enum_method_id(other), 0, 0,
                rb_block_given_p() ? set_initialize_with_block : set_initialize_without_block,
                set);
        }
    }

    return set;
}

Class Method Details

.[](*args)

[ GitHub ]

  
# File 'set.c', line 409

static VALUE
set_s_create(int argc, VALUE *argv, VALUE klass)
{
    VALUE set = set_alloc_with_size(klass, argc);
    set_table *table = RSET_TABLE(set);
    int i;

    for (i=0; i < argc; i++) {
        set_table_insert_wb(table, set, argv[i], NULL);
    }

    return set;
}

Instance Attribute Details

#compare_by_identityself (readonly)

Makes the set compare its elements by their identity and returns self.

[ GitHub ]

  
# File 'set.c', line 1197

static VALUE
set_i_compare_by_identity(VALUE set)
{
    if (RSET_COMPARE_BY_IDENTITY(set)) return set;

    if (set_iterating_p(set)) {
        rb_raise(rb_eRuntimeError, "compare_by_identity during iteration");
    }

    return set_reset_table_with_type(set, &identhash);
}

#compare_by_identity?Boolean (readonly)

Returns true if the set will compare its elements by their identity. Also see #compare_by_identity.

[ GitHub ]

  
# File 'set.c', line 1216

static VALUE
set_i_compare_by_identity_p(VALUE set)
{
    return RBOOL(RSET_COMPARE_BY_IDENTITY(set));
}

#empty?Boolean (readonly)

Returns true if the set contains no elements.

[ GitHub ]

  
# File 'set.c', line 1240

static VALUE
set_i_empty(VALUE set)
{
    return RBOOL(RSET_EMPTY(set));
}

Instance Method Details

#&(enum) ⇒ Set Also known as: #intersection

Returns a new set containing elements common to the set and the given enumerable object.

Set[1, 3, 5] & Set[3, 2, 1]             #=> #<Set: {3, 1}>
Set['a', 'b', 'z'] & ['a', 'b', 'c']    #=> #<Set: {"a", "b"}>
[ GitHub ]

  
# File 'set.c', line 1028

static VALUE
set_i_intersection(VALUE set, VALUE other)
{
    VALUE new_set = set_s_alloc(rb_obj_class(set));
    set_table *stable = RSET_TABLE(set);
    set_table *ntable = RSET_TABLE(new_set);

    if (rb_obj_is_kind_of(other, rb_cSet)) {
        set_table *otable = RSET_TABLE(other);
        if (set_table_size(stable) >= set_table_size(otable)) {
            /* Swap so we iterate over the smaller set */
            otable = stable;
            set = other;
        }

        struct set_intersection_data data = {
            .set = new_set,
            .into = ntable,
            .other = otable
        };
        set_iter(set, set_intersection_i, (st_data_t)&data);
    }
    else {
        struct set_intersection_data data = {
            .set = new_set,
            .into = ntable,
            .other = stable
        };
        rb_block_call(other, enum_method_id(other), 0, 0, set_intersection_block, (VALUE)&data);
    }

    return new_set;
}

#+(enum) ⇒ Set Also known as: #|, #union

Returns a new set built by merging the set and the elements of the given enumerable object.

Set[1, 2, 3] | Set[2, 4, 5]         #=> #<Set: {1, 2, 3, 4, 5}>
Set[1, 5, 'z'] | (1..6)             #=> #<Set: {1, 5, "z", 2, 3, 4, 6}>
[ GitHub ]

  
# File 'set.c', line 1294

static VALUE
set_i_union(VALUE set, VALUE other)
{
    set = rb_obj_dup(set);
    set_merge_enum_into(set, other);
    return set;
}

#-(enum) ⇒ Set Also known as: #difference

Returns a new set built by duplicating the set, removing every element that appears in the given enumerable object.

Set[1, 3, 5] - Set[1, 5]                #=> #<Set: {3}>
Set['a', 'b', 'z'] - ['a', 'c']         #=> #<Set: {"b", "z"}>
[ GitHub ]

  
# File 'set.c', line 1353

static VALUE
set_i_difference(VALUE set, VALUE other)
{
    return set_i_subtract(rb_obj_dup(set), other);
}

#<(set) ⇒ Boolean Also known as: #proper_subset?

Returns true if the set is a proper subset of the given set.

[ GitHub ]

  
# File 'set.c', line 1620

static VALUE
set_i_proper_subset(VALUE set, VALUE other)
{
    check_set(other);
    if (RSET_SIZE(set) >= RSET_SIZE(other)) return Qfalse;
    return set_le(set, other);
}

#<<(obj) ⇒ self Also known as: #add

Adds the given object to the set and returns self. Use #merge to add many elements at once.

Set[1, 2].add(3)                    #=> #<Set: {1, 2, 3}>
Set[1, 2].add([3, 4])               #=> #<Set: {1, 2, [3, 4]}>
Set[1, 2].add(2)                    #=> #<Set: {1, 2}>
[ GitHub ]

  
# File 'set.c', line 680

static VALUE
set_i_add(VALUE set, VALUE item)
{
    rb_check_frozen(set);
    if (set_iterating_p(set)) {
        if (!set_lookup(RSET_TABLE(set), (st_data_t)item)) {
            no_new_item();
        }
    }
    else {
        set_insert_wb(set, item, NULL);
    }
    return set;
}

#<=(set) ⇒ Boolean Also known as: #subset?

Returns true if the set is a subset of the given set.

[ GitHub ]

  
# File 'set.c', line 1634

static VALUE
set_i_subset(VALUE set, VALUE other)
{
    check_set(other);
    if (RSET_SIZE(set) > RSET_SIZE(other)) return Qfalse;
    return set_le(set, other);
}

#<=>(other) ⇒ 1, ...

Returns 0 if the set are equal, -1 / 1 if the set is a proper subset / superset of the given set, or or nil if they both have unique elements.

[ GitHub ]

  
# File 'set.c', line 1748

static VALUE
set_i_compare(VALUE set, VALUE other)
{
    if (rb_obj_is_kind_of(other, rb_cSet)) {
        size_t set_size = RSET_SIZE(set);
        size_t other_size = RSET_SIZE(other);

        if (set_size < other_size) {
            if (set_le(set, other) == Qtrue) {
                return INT2NUM(-1);
            }
        }
        else if (set_size > other_size) {
            if (set_le(other, set) == Qtrue) {
                return INT2NUM(1);
            }
        }
        else if (set_le(set, other) == Qtrue) {
            return INT2NUM(0);
        }
    }

    return Qnil;
}

#==(other) ⇒ Boolean Also known as: #eql?

Returns true if two sets are equal.

[ GitHub ]

  
# File 'set.c', line 1806

static VALUE
set_i_eq(VALUE set, VALUE other)
{
    if (!rb_obj_is_kind_of(other, rb_cSet)) return Qfalse;
    if (set == other) return Qtrue;

    set_table *stable = RSET_TABLE(set);
    set_table *otable = RSET_TABLE(other);
    size_t ssize = set_table_size(stable);
    size_t osize = set_table_size(otable);

    if (ssize != osize) return Qfalse;
    if (ssize == 0 && osize == 0) return Qtrue;
    if (stable->type != otable->type) return Qfalse;

    struct set_equal_data data;
    data.set = other;
    return rb_exec_recursive_paired(set_recursive_eql, set, other, (VALUE)&data);
}

#===(item) ⇒ Boolean Also known as: #include?, #member?

Returns true if the set contains the given object:

Set[1, 2, 3].include? 2   #=> true
Set[1, 2, 3].include? 4   #=> false

Note that #include? and #member? do not test member equality using #== as do other Enumerables.

This is aliased to #===, so it is usable in case expressions:

case :apple
when Set[:potato, :carrot]
  "vegetable"
when Set[:apple, :banana]
  "fruit"
end
# => "fruit"

See also Enumerable#include?

[ GitHub ]

  
# File 'set.c', line 1086

static VALUE
set_i_include(VALUE set, VALUE item)
{
    return RBOOL(RSET_IS_MEMBER(set, item));
}

#>(set) ⇒ Boolean Also known as: #proper_superset?

Returns true if the set is a proper superset of the given set.

[ GitHub ]

  
# File 'set.c', line 1648

static VALUE
set_i_proper_superset(VALUE set, VALUE other)
{
    check_set(other);
    if (RSET_SIZE(set) <= RSET_SIZE(other)) return Qfalse;
    return set_le(other, set);
}

#>=(set) ⇒ Boolean Also known as: #superset?

Returns true if the set is a superset of the given set.

[ GitHub ]

  
# File 'set.c', line 1662

static VALUE
set_i_superset(VALUE set, VALUE other)
{
    check_set(other);
    if (RSET_SIZE(set) < RSET_SIZE(other)) return Qfalse;
    return set_le(other, set);
}

#^(enum) ⇒ Set

Returns a new set containing elements exclusive between the set and the given enumerable object. (set ^ enum) is equivalent to ((set | enum) - (set & enum)).

Set[1, 2] ^ Set[2, 3]                   #=> #<Set: {3, 1}>
Set[1, 'b', 'c'] ^ ['b', 'd']           #=> #<Set: {"d", 1, "c"}>
[ GitHub ]

  
# File 'set.c', line 1269

static VALUE
set_i_xor(VALUE set, VALUE other)
{
    VALUE new_set;
    if (rb_obj_is_kind_of(other, rb_cSet)) {
        new_set = other;
    }
    else {
        new_set = set_s_alloc(rb_obj_class(set));
        set_merge_enum_into(new_set, other);
    }
    set_iter(set, set_xor_i, (st_data_t)new_set);
    return new_set;
}

#<<(obj) ⇒ self #add(obj) ⇒ self

Alias for #<<.

#add?(obj) ⇒ self?

Adds the given object to the set and returns self. If the object is already in the set, returns nil.

Set[1, 2].add?(3)                    #=> #<Set: {1, 2, 3}>
Set[1, 2].add?([3, 4])               #=> #<Set: {1, 2, [3, 4]}>
Set[1, 2].add?(2)                    #=> nil
[ GitHub ]

  
# File 'set.c', line 706

static VALUE
set_i_add_p(VALUE set, VALUE item)
{
    rb_check_frozen(set);
    if (set_iterating_p(set)) {
        if (!set_lookup(RSET_TABLE(set), (st_data_t)item)) {
            no_new_item();
        }
        return Qnil;
    }
    else {
        return set_insert_wb(set, item, NULL) ? Qnil : set;
    }
}

#classify {|o| ... } ⇒ Hash #classifyEnumerator

Classifies the set by the return value of the given block and returns a hash of => set of elements pairs. The block is called once for each element of the set, passing the element as parameter.

files = Set.new(Dir.glob("*.rb"))
hash = files.classify { |f| File.mtime(f).year }
hash       #=> {2000 => #<Set: {"a.rb", "b.rb"}>,
           #    2001 => #<Set: {"c.rb", "d.rb", "e.rb"}>,
           #    2002 => #<Set: {"f.rb"}>}

Returns an enumerator if no block is given.

[ GitHub ]

  
# File 'set.c', line 838

static VALUE
set_i_classify(VALUE set)
{
    RETURN_SIZED_ENUMERATOR(set, 0, 0, set_enum_size);
    VALUE args[2];
    args[0] = rb_hash_new();
    args[1] = rb_obj_class(set);
    set_iter(set, set_classify_i, (st_data_t)args);
    return args[0];
}

#clearself

Removes all elements and returns self.

set = Set[1, 'c', :s]             #=> #<Set: {1, "c", :s}>
set.clear                         #=> #<Set: {}>
set                               #=> #<Set: {}>
[ GitHub ]

  
# File 'set.c', line 979

static VALUE
set_i_clear(VALUE set)
{
    rb_check_frozen(set);
    if (RSET_SIZE(set) == 0) return set;
    if (set_iterating_p(set)) {
        set_iter(set, set_clear_i, 0);
    }
    else {
        set_clear(RSET_TABLE(set));
        set_compact_after_delete(set);
    }
    return set;
}

#collect! {|o| ... } ⇒ self #collect!Enumerator

Alias for #map!.

#delete(obj) ⇒ self

Deletes the given object from the set and returns self. Use subtract to delete many items at once.

[ GitHub ]

  
# File 'set.c', line 728

static VALUE
set_i_delete(VALUE set, VALUE item)
{
    rb_check_frozen(set);
    if (set_delete(RSET_TABLE(set), (st_data_t *)&item)) {
        set_compact_after_delete(set);
    }
    return set;
}

#delete?(obj) ⇒ self?

Deletes the given object from the set and returns self. If the object is not in the set, returns nil.

[ GitHub ]

  
# File 'set.c', line 745

static VALUE
set_i_delete_p(VALUE set, VALUE item)
{
    rb_check_frozen(set);
    if (set_delete(RSET_TABLE(set), (st_data_t *)&item)) {
        set_compact_after_delete(set);
        return set;
    }
    return Qnil;
}

#delete_if {|o| ... } ⇒ self #delete_ifEnumerator

Deletes every element of the set for which block evaluates to true, and returns self. Returns an enumerator if no block is given.

[ GitHub ]

  
# File 'set.c', line 770

static VALUE
set_i_delete_if(VALUE set)
{
    RETURN_SIZED_ENUMERATOR(set, 0, 0, set_enum_size);
    rb_check_frozen(set);
    set_iter(set, set_delete_if_i, 0);
    set_compact_after_delete(set);
    return set;
}

#-(enum) ⇒ Set #difference(enum) ⇒ Set

Alias for #-.

#disjoint?(set) ⇒ Boolean

Returns true if the set and the given enumerable have no element in common. This method is the opposite of #intersect?.

Set[1, 2, 3].disjoint? Set[3, 4]   #=> false
Set[1, 2, 3].disjoint? Set[4, 5]   #=> true
Set[1, 2, 3].disjoint? [3, 4]      #=> false
Set[1, 2, 3].disjoint? 4..5        #=> true
[ GitHub ]

  
# File 'set.c', line 1734

static VALUE
set_i_disjoint(VALUE set, VALUE other)
{
    return RBOOL(!RTEST(set_i_intersect(set, other)));
}

#divide {|o1, o2| ... } ⇒ Set #divide {|o| ... } ⇒ Set #divideEnumerator

Divides the set into a set of subsets according to the commonality defined by the given block.

If the arity of the block is 2, elements o1 and o2 are in common if both block.call(o1, o2) and block.call(o2, o1) are true. Otherwise, elements o1 and o2 are in common if block.call(o1) == block.call(o2).

numbers = Set[1, 3, 4, 6, 9, 10, 11]
set = numbers.divide { |i,j| (i - j).abs == 1 }
set        #=> #<Set: {#<Set: {1}>,
           #           #<Set: {3, 4}>,
           #           #<Set: {6}>}>
           #           #<Set: {9, 10, 11}>,

Returns an enumerator if no block is given.

[ GitHub ]

  
# File 'set.c', line 936

static VALUE
set_i_divide(VALUE set)
{
    RETURN_SIZED_ENUMERATOR(set, 0, 0, set_enum_size);

    if (rb_block_arity() == 2) {
        VALUE final_set = set_s_create(0, 0, rb_cSet);
        struct set_divide_args args = {
            .self = set,
            .set_class = rb_obj_class(set),
            .final_set = final_set,
            .hash = rb_hash_new(),
            .current_set = 0,
            .current_item = 0,
            .ni = 0,
            .nj = 0
        };
        rb_block_call(set, id_each, 0, 0, set_divide_block, (VALUE)&args);
        return final_set;
    }

    VALUE values = rb_hash_values(set_i_classify(set));
    set = set_alloc_with_size(rb_cSet, RARRAY_LEN(values));
    set_merge_enum_into(set, values);
    return set;
}

#each {|o| ... } ⇒ self #eachEnumerator

Calls the given block once for each element in the set, passing the element as parameter. Returns an enumerator if no block is given.

[ GitHub ]

  
# File 'set.c', line 1375

static VALUE
set_i_each(VALUE set)
{
    RETURN_SIZED_ENUMERATOR(set, 0, 0, set_enum_size);
    set_iter(set, set_each_i, 0);
    return set;
}

#==(other) ⇒ Boolean #eql?(other) ⇒ Boolean

Alias for #==.

#select! {|o| ... } ⇒ self #select!Enumerator
Also known as: #select!

Equivalent to #keep_if, but returns nil if no changes were made. Returns an enumerator if no block is given.

[ GitHub ]

  
# File 'set.c', line 1447

static VALUE
set_i_select(VALUE set)
{
    RETURN_SIZED_ENUMERATOR(set, 0, 0, set_enum_size);
    rb_check_frozen(set);

    set_table *table = RSET_TABLE(set);
    size_t n = set_table_size(table);
    set_iter(set, set_keep_if_i, (st_data_t)table);

    return (n == set_table_size(table)) ? Qnil : set;
}

#flattenSet

Returns a new set that is a copy of the set, flattening each containing set recursively.

[ GitHub ]

  
# File 'set.c', line 1554

static VALUE
set_i_flatten(VALUE set)
{
    VALUE new_set = set_s_alloc(rb_obj_class(set));
    set_flatten_merge(new_set, set, rb_hash_new());
    return new_set;
}

#flatten!self

Equivalent to #flatten, but replaces the receiver with the result in place. Returns nil if no modifications were made.

[ GitHub ]

  
# File 'set.c', line 1579

static VALUE
set_i_flatten_bang(VALUE set)
{
    bool contains_set = false;
    set_iter(set, set_contains_set_i, (st_data_t)&contains_set);
    if (!contains_set) return Qnil;
    rb_check_frozen(set);
    return set_i_replace(set, set_i_flatten(set));
}

#hashInteger

Returns hash code for set.

[ GitHub ]

  
# File 'set.c', line 1841

static VALUE
set_i_hash(VALUE set)
{
    st_index_t size = RSET_SIZE(set);
    st_index_t hval = rb_st_hash_start(size);
    hval = rb_hash_uint(hval, (st_index_t)set_i_hash);
    if (size) {
        set_iter(set, set_hash_i, (VALUE)&hval);
    }
    hval = rb_st_hash_end(hval);
    return ST2FIX(hval);
}

#===(item) ⇒ Boolean #include?(item) ⇒ Boolean

Alias for #===.

#initialize_copy(other)

[ GitHub ]

  
# File 'set.c', line 522

static VALUE
set_i_initialize_copy(VALUE set, VALUE other)
{
    if (set == other) return set;

    if (set_iterating_p(set)) {
        rb_raise(rb_eRuntimeError, "cannot replace set during iteration");
    }

    struct set_object *sobj;
    TypedData_Get_Struct(set, struct set_object, &set_data_type, sobj);

    set_free_embedded(sobj);
    set_copy(&sobj->table, RSET_TABLE(other));

    return set;
}

#to_sString #inspectString

Alias for #to_s.

#intersect?(set) ⇒ Boolean

Returns true if the set and the given enumerable have at least one element in common.

Set[1, 2, 3].intersect? Set[4, 5]   #=> false
Set[1, 2, 3].intersect? Set[3, 4]   #=> true
Set[1, 2, 3].intersect? 4..5        #=> false
Set[1, 2, 3].intersect? [3, 4]      #=> true
[ GitHub ]

  
# File 'set.c', line 1693

static VALUE
set_i_intersect(VALUE set, VALUE other)
{
    if (rb_obj_is_kind_of(other, rb_cSet)) {
        size_t set_size = RSET_SIZE(set);
        size_t other_size = RSET_SIZE(other);
        VALUE args[2];
        args[1] = Qfalse;
        VALUE iter_arg;

        if (set_size < other_size) {
            iter_arg = set;
            args[0] = (VALUE)RSET_TABLE(other);
        }
        else {
            iter_arg = other;
            args[0] = (VALUE)RSET_TABLE(set);
        }
        set_iter(iter_arg, set_intersect_i, (st_data_t)args);
        return args[1];
    }
    else if (rb_obj_is_kind_of(other, rb_mEnumerable)) {
        return rb_funcall(other, id_any_p, 1, set);
    }
    else {
        rb_raise(rb_eArgError, "value must be enumerable");
    }
}

#&(enum) ⇒ Set #intersection(enum) ⇒ Set

Alias for #&.

#join(separator=nil)-> new_string)

Returns a string created by converting each element of the set to a string.

[ GitHub ]

  
# File 'set.c', line 662

static VALUE
set_i_join(int argc, VALUE *argv, VALUE set)
{
    rb_check_arity(argc, 0, 1);
    return rb_ary_join(set_i_to_a(set), argc == 0 ? Qnil : argv[0]);
}

#keep_if {|o| ... } ⇒ self #keep_ifEnumerator

Deletes every element of the set for which block evaluates to false, and returns self. Returns an enumerator if no block is given.

[ GitHub ]

  
# File 'set.c', line 1428

static VALUE
set_i_keep_if(VALUE set)
{
    RETURN_SIZED_ENUMERATOR(set, 0, 0, set_enum_size);
    rb_check_frozen(set);

    set_iter(set, set_keep_if_i, (st_data_t)RSET_TABLE(set));

    return set;
}

#lengthInteger Also known as: #size

Returns the number of elements.

[ GitHub ]

  
# File 'set.c', line 1228

static VALUE
set_i_size(VALUE set)
{
    return RSET_SIZE_NUM(set);
}

#collect! {|o| ... } ⇒ self #collect!Enumerator
Also known as: #collect!

Replaces the elements with ones returned by collect. Returns an enumerator if no block is given.

[ GitHub ]

  
# File 'set.c', line 1398

static VALUE
set_i_collect(VALUE set)
{
    RETURN_SIZED_ENUMERATOR(set, 0, 0, set_enum_size);
    rb_check_frozen(set);

    VALUE new_set = set_s_alloc(rb_obj_class(set));
    set_iter(set, set_collect_i, (st_data_t)new_set);
    set_i_initialize_copy(set, new_set);

    return set;
}

#===(item) ⇒ Boolean #member?(item) ⇒ Boolean

Alias for #===.

#merge(*enums, **nil) ⇒ self

Merges the elements of the given enumerable objects to the set and returns self.

[ GitHub ]

  
# File 'set.c', line 1146

static VALUE
set_i_merge(int argc, VALUE *argv, VALUE set)
{
    if (rb_keyword_given_p()) {
        rb_raise(rb_eArgError, "no keywords accepted");
    }
    rb_check_frozen(set);

    int i;

    for (i=0; i < argc; i++) {
        set_merge_enum_into(set, argv[i]);
    }

    return set;
}

#<(set) ⇒ Boolean #proper_subset?(set) ⇒ Boolean

Alias for #<.

#>(set) ⇒ Boolean #proper_superset?(set) ⇒ Boolean

Alias for #>.

#reject! {|o| ... } ⇒ self #reject!Enumerator

Equivalent to #delete_if, but returns nil if no changes were made. Returns an enumerator if no block is given.

[ GitHub ]

  
# File 'set.c', line 788

static VALUE
set_i_reject(VALUE set)
{
    RETURN_SIZED_ENUMERATOR(set, 0, 0, set_enum_size);
    rb_check_frozen(set);

    set_table *table = RSET_TABLE(set);
    size_t n = set_table_size(table);
    set_iter(set, set_delete_if_i, 0);

    if (n == set_table_size(table)) return Qnil;

    set_compact_after_delete(set);
    return set;
}

#replace(enum) ⇒ self

Replaces the contents of the set with the contents of the given enumerable object and returns self.

set = Set[1, 'c', :s]             #=> #<Set: {1, "c", :s}>
set.replace([1, 2])               #=> #<Set: {1, 2}>
set                               #=> #<Set: {1, 2}>
[ GitHub ]

  
# File 'set.c', line 1471

static VALUE
set_i_replace(VALUE set, VALUE other)
{
    rb_check_frozen(set);

    if (rb_obj_is_kind_of(other, rb_cSet)) {
        set_i_initialize_copy(set, other);
    }
    else {
        if (set_iterating_p(set)) {
            rb_raise(rb_eRuntimeError, "cannot replace set during iteration");
        }

        // make sure enum is enumerable before calling clear
        enum_method_id(other);

        set_clear(RSET_TABLE(set));
        set_merge_enum_into(set, other);
    }

    return set;
}

#resetself

Resets the internal state after modification to existing elements and returns self. Elements will be reindexed and deduplicated.

[ GitHub ]

  
# File 'set.c', line 1501

static VALUE
set_i_reset(VALUE set)
{
    if (set_iterating_p(set)) {
        rb_raise(rb_eRuntimeError, "reset during iteration");
    }

    return set_reset_table_with_type(set, RSET_TABLE(set)->type);
}

#select! {|o| ... } ⇒ self #select!Enumerator

Alias for #filter!.

#lengthInteger #sizeInteger

Alias for #length.

#<=(set) ⇒ Boolean #subset?(set) ⇒ Boolean

Alias for #<=.

#subtract(enum) ⇒ self

Deletes every element that appears in the given enumerable object and returns self.

[ GitHub ]

  
# File 'set.c', line 1335

static VALUE
set_i_subtract(VALUE set, VALUE other)
{
    rb_check_frozen(set);
    set_remove_enum_from(set, other);
    return set;
}

#>=(set) ⇒ Boolean #superset?(set) ⇒ Boolean

Alias for #>=.

#to_aArray

Returns an array containing all elements in the set.

Set[1, 2].to_a                    #=> [1, 2]
Set[1, 'c', :s].to_a              #=> [1, "c", :s]
[ GitHub ]

  
# File 'set.c', line 602

static VALUE
set_i_to_a(VALUE set)
{
    st_index_t size = RSET_SIZE(set);
    VALUE ary = rb_ary_new_capa(size);

    if (size == 0) return ary;

    if (ST_DATA_COMPATIBLE_P(VALUE)) {
        RARRAY_PTR_USE(ary, ptr, {
            size = set_keys(RSET_TABLE(set), ptr, size);
        });
        rb_gc_writebarrier_remember(ary);
        rb_ary_set_len(ary, size);
    }
    else {
        set_iter(set, set_to_a_i, (st_data_t)ary);
    }
    return ary;
}

#to_h

[ GitHub ]

  
# File 'set.c', line 1862

static VALUE
set_i_to_h(VALUE set)
{
    st_index_t size = RSET_SIZE(set);
    VALUE hash;
    if (RSET_COMPARE_BY_IDENTITY(set)) {
        hash = rb_ident_hash_new_with_size(size);
    }
    else {
        hash = rb_hash_new_with_size(size);
    }
    rb_hash_set_default(hash, Qfalse);

    if (size == 0) return hash;

    set_iter(set, set_to_hash_i, (st_data_t)hash);
    return hash;
}

#to_sString Also known as: #inspect

Returns a new string containing the set entries:

s = Set.new
s.inspect # => "#<Set: {}>"
s.add(1)
s.inspect # => "#<Set: {1}>"
s.add(2)
s.inspect # => "#<Set: {1, 2}>"

Related: see Methods for Converting.

[ GitHub ]

  
# File 'set.c', line 580

static VALUE
set_i_inspect(VALUE set)
{
    return rb_exec_recursive(set_inspect, set, 0);
}

#to_set(klass = Set, *args, &block) ⇒ self, Set

Returns self if receiver is an instance of Set and no arguments or block are given. Otherwise, converts the set to another with klass.new(self, *args, &block).

In subclasses, returns klass.new(self, *args, &block) unless overridden.

[ GitHub ]

  
# File 'set.c', line 633

static VALUE
set_i_to_set(int argc, VALUE *argv, VALUE set)
{
    VALUE klass;

    if (argc == 0) {
        klass = rb_cSet;
        argv = &set;
        argc = 1;
    }
    else {
        klass = argv[0];
        argv[0] = set;
    }

    if (klass == rb_cSet && rb_obj_is_instance_of(set, rb_cSet) &&
            argc == 1 && !rb_block_given_p()) {
        return set;
    }

    return rb_funcall_passing_block(klass, id_new, argc, argv);
}

#+(enum) ⇒ Set #union(enum) ⇒ Set

Alias for #+.

#+(enum) ⇒ Set #|(enum) ⇒ Set

Alias for #+.