Spec-Zone.ru › Ruby 4.0

класс Set

Родительский класс:
Object
Подключенные модули:
Enumerable

Класс Set реализует коллекцию неупорядоченных значений без дубликатов. Это гибрид интуитивно понятных средств взаимодействия с Array и быстрого поиска Hash.

Set удобно использовать с объектами Enumerable (реализующими each). Большинство методов инициализации и бинарных операторов принимают универсальные объекты Enumerable в дополнение к множествам и массивам. Объект Enumerable можно преобразовать в Set с помощью метода to_set.

Для хранения Set использует структуру данных, аналогичную Hash, за исключением того, что в ней есть только ключи, но нет значений.

  • Равенство элементов определяется согласно Object#eql? и Object#hash. Используйте Set#compare_by_identity, чтобы множество сравнивало элементы по их идентичности.

  • Set предполагает, что идентичность каждого элемента не меняется, пока он хранится в множестве. Изменение элемента множества приведет к тому, что множество станет ненадежным.

  • При добавлении строки сохраняется ее замороженная копия, если исходная строка еще не заморожена.

Сравнение

Операторы сравнения <, >, <= и >= реализованы как сокращенные формы методов {proper_,}{subset?,superset?}. Оператор <=> отражает этот порядок или возвращает nil для множеств, в которых есть различные элементы (например, {x, y} и {x, z}).

Пример

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

Контакты

  • Akinori MUSHA <knu@iDaemons.org> (текущий сопровождающий)

Наследование от Set

До Ruby 4.0 (выпущенной в декабре 2025 года) Set имел другую, менее эффективную реализацию. Он был реализован заново на C, а поведение некоторых основных методов было скорректировано.

Для обратной совместимости при наследовании класса от Set подключается дополнительный модуль Set::SubclassCompatible, который делает поведение унаследованного класса и имена внутренних методов более похожими на те, что были до Ruby 4.0.

Это легко увидеть, например, по поведению метода inspect:

p Set[1, 2, 3]
# prints "Set[1, 2, 3]"

class MySet < Set
end
p MySet[1, 2, 3]
# prints "#<MySet: {1, 2, 3}>", like it was in Ruby 3.4

В новом коде, если обратная совместимость не требуется, рекомендуется наследоваться от Set::CoreSet, чтобы избежать подключения слоя «совместимости»:

class MyCoreSet < Set::CoreSet
end
p MyCoreSet[1, 2, 3]
# prints "MyCoreSet[1, 2, 3]"

Методы Set

Сначала рассмотрим, что находится в других местах. Класс Set:

  • Наследуется от класса Object.

  • Подключает модуль Enumerable, который предоставляет десятки дополнительных методов.

В частности, у класса Set мало собственных методов для получения элементов и итерации. Вместо этого он использует методы из Enumerable.

Здесь представлены методы класса Set, полезные для:

  • Создания множества

  • Операций над множествами

  • Сравнения

  • Запросов

  • Добавления элементов

  • Удаления элементов

  • Преобразования

  • Итерации

  • И многое другое.…

Методы создания множества

  • ::[]: Возвращает новое множество, содержащее заданные объекты.

  • ::new: Возвращает новое множество, содержащее либо заданные объекты (если блок не передан), либо значения, возвращенные вызванным блоком (если блок передан).

Методы для операций над множествами

  • | (также доступен под именами union и +): Возвращает новое множество, содержащее все элементы из self и все элементы из заданного перечислимого объекта (без дубликатов).

  • & (также доступен под именем intersection): Возвращает новое множество, содержащее все общие элементы self и заданного перечислимого объекта.

  • - (также доступен под именем difference): Возвращает копию self без всех элементов, присутствующих в заданном перечислимом объекте.

  • ^: Возвращает новое множество, содержащее все элементы из self и заданного перечислимого объекта, за исключением общих для них элементов.

Методы сравнения

  • <=>: Возвращает -1, 0 или 1 в зависимости от того, меньше ли self заданного объекта, равно ему или больше него.

  • ==: Возвращает признак равенства self и заданного перечислимого объекта, определяемого с помощью Object#eql?.

  • compare_by_identity?: Возвращает признак того, что множество учитывает только идентичность при сравнении элементов.

Методы запросов

  • length (также доступен под именем size): Возвращает количество элементов.

  • empty?: Возвращает признак того, что множество не содержит элементов.

  • include? (также доступен под именами member? и ===): Возвращает признак того, что заданный объект является элементом множества.

  • subset? (также доступен под именем <=): Возвращает признак того, что заданный объект является подмножеством этого множества.

  • proper_subset? (также доступен под именем <): Возвращает признак того, что заданный перечислимый объект является собственным подмножеством этого множества.

  • superset? (также доступен под именем >=): Возвращает признак того, что заданный перечислимый объект является надмножеством этого множества.

  • proper_superset? (также доступен под именем >): Возвращает признак того, что заданный перечислимый объект является собственным надмножеством этого множества.

  • disjoint?: Возвращает true, если у множества и заданного перечислимого объекта нет общих элементов, и false в противном случае.

  • intersect?: Возвращает true, если у множества и заданного перечислимого объекта есть общие элементы, и false в противном случае.

  • compare_by_identity?: Возвращает признак того, что множество учитывает только идентичность при сравнении элементов.

Методы добавления элементов

  • add (также доступен под именем <<): Добавляет заданный объект в множество; возвращает self.

  • add?: Если заданный объект не является элементом множества, добавляет его и возвращает self; в противном случае возвращает nil.

  • merge: Добавляет в множество элементы каждого из заданных перечислимых объектов; возвращает self.

  • replace: Заменяет содержимое множества содержимым заданного перечислимого объекта.

Методы удаления элементов

  • clear: Удаляет все элементы множества; возвращает self.

  • delete: Удаляет заданный объект из множества; возвращает self.

  • delete?: Если заданный объект является элементом множества, удаляет его и возвращает self; в противном случае возвращает nil.

  • subtract: Удаляет каждый заданный объект из множества; возвращает self.

  • delete_if - Удаляет элементы, указанные заданным блоком.

  • select! (также доступен под именем filter!): Удаляет элементы, не указанные заданным блоком.

  • keep_if: Удаляет элементы, не указанные заданным блоком.

  • reject! Удаляет элементы, указанные заданным блоком.

Методы преобразования

  • classify: Возвращает хеш, группирующий элементы согласно заданному блоку.

  • collect! (также доступен под именем map!): Заменяет каждый элемент значением, возвращенным блоком.

  • divide: Возвращает хеш, группирующий элементы согласно заданному блоку; отличается от classify тем, что блок может принимать один или два аргумента.

  • flatten: Возвращает новое множество, представляющее собой рекурсивно выровненное self.

  • flatten!: Заменяет каждое вложенное множество в self элементами этого множества.

  • inspect (также доступен под именем to_s): Возвращает строку, отображающую элементы.

  • join: Возвращает строку, содержащую все элементы, при необходимости преобразованные в строки и объединенные заданным разделителем записей.

  • to_a: Возвращает массив, содержащий все элементы множества.

  • to_set: Если аргументы и блок не заданы, возвращает self; если задан блок, возвращает новое множество из значений, возвращенных блоком.

Методы итерации

  • each: Вызывает блок для каждого следующего элемента; возвращает self.

Другие методы

  • reset: Сбрасывает внутреннее состояние; полезен, если объект был изменен, пока являлся элементом множества.

Публичные методы класса

Set[*objects] → new_set Показать исходный код
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;
}

Возвращает новый объект Set, заполненный заданными объектами. См. Set::new.

json_create (object) Показать исходный код
# File ext/json/lib/json/add/set.rb, line 9
def self.json_create(object)
  new object['a']
end

См. as_json.

new → new_set Показать исходный код
new(enum) → new_set
new(enum) { |elem| ... } → new_set
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 i;
            int block_given = rb_block_given_p();
            set_table *into = RSET_TABLE(set);
            for (i=0; i<RARRAY_LEN(other); i++) {
                VALUE key = RARRAY_AREF(other, i);
                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;
}

Создает новое множество, содержащее элементы заданного перечислимого объекта.

Если передан блок, элементы enum предварительно обрабатываются этим блоком.

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]

Открытые методы экземпляра

set & enum → new_set Показать исходный код
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;
}

Возвращает новое множество, содержащее элементы, общие для этого множества и заданного перечислимого объекта.

Set[1, 3, 5] & Set[3, 2, 1]             #=> Set[3, 1]
Set['a', 'b', 'z'] & ['a', 'b', 'c']    #=> Set["a", "b"]
Также имеет псевдоним: intersection
+
Псевдоним для: |
set - enum → new_set Показать исходный код
static VALUE
set_i_difference(VALUE set, VALUE other)
{
    return set_i_subtract(rb_obj_dup(set), other);
}

Возвращает новое множество, созданное как копия этого множества, из которой удалён каждый элемент, встречающийся в заданном перечислимом объекте.

Set[1, 3, 5] - Set[1, 5]                #=> Set[3]
Set['a', 'b', 'z'] - ['a', 'c']         #=> Set["b", "z"]
Также имеет псевдоним: difference
<
Псевдоним для: proper_subset?
<<
Псевдоним для: add
<=
Псевдоним для: subset?
set <=> other → -1, 0, 1, or nil Показать исходный код
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;
}

Возвращает 0, если множества равны, -1 / 1, если это множество является собственным подмножеством / надмножеством заданного множества, или nil, если в каждом из них есть уникальные элементы.

set == other → true or false Показать исходный код
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);
}

Возвращает true, если два множества равны.

Также имеет псевдоним: eql?
===
Псевдоним для: include?
>
Псевдоним для: proper_superset?
>=
Псевдоним для: superset?
set ^ enum → new_set Показать исходный код
static VALUE
set_i_xor(VALUE set, VALUE other)
{
    VALUE new_set = rb_obj_dup(set);

    if (rb_obj_is_kind_of(other, rb_cSet)) {
        set_iter(other, set_xor_i, (st_data_t)new_set);
    }
    else {
        VALUE tmp = set_s_alloc(rb_cSet);
        set_merge_enum_into(tmp, other);
        set_iter(tmp, set_xor_i, (st_data_t)new_set);
    }

    return new_set;
}

Возвращает новое множество, содержащее элементы, входящие только в одно из двух множеств: это множество и заданный перечислимый объект. (set ^ enum) эквивалентно ((set | enum) - (set & enum)).

Set[1, 2] ^ Set[2, 3]                   #=> Set[3, 1]
Set[1, 'b', 'c'] ^ ['b', 'd']           #=> Set["d", 1, "c"]
set | enum → new_set Показать исходный код
static VALUE
set_i_union(VALUE set, VALUE other)
{
    set = rb_obj_dup(set);
    set_merge_enum_into(set, other);
    return set;
}

Возвращает новое множество, созданное путём объединения этого множества с элементами заданного перечислимого объекта.

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]
Также имеет псевдонимы: +, union
add(obj) → self Показать исходный код
static VALUE
set_i_add(VALUE set, VALUE item)
{
    rb_check_frozen(set);
    if (set_iterating_p(set)) {
        if (!set_table_lookup(RSET_TABLE(set), (st_data_t)item)) {
            no_new_item();
        }
    }
    else {
        set_insert_wb(set, item, NULL);
    }
    return set;
}

Добавляет заданный объект в множество и возвращает self. Чтобы добавить сразу несколько элементов, используйте Set#merge.

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]
Также имеет псевдоним: <<
add?(obj) → self or nil Показать исходный код
static VALUE
set_i_add_p(VALUE set, VALUE item)
{
    rb_check_frozen(set);
    if (set_iterating_p(set)) {
        if (!set_table_lookup(RSET_TABLE(set), (st_data_t)item)) {
            no_new_item();
        }
        return Qnil;
    }
    else {
        return set_insert_wb(set, item, NULL) ? Qnil : set;
    }
}

Добавляет заданный объект в множество и возвращает self. Если объект уже есть в множестве, возвращает 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
as_json (*) Показать исходный код
# File ext/json/lib/json/add/set.rb, line 28
def as_json(*)
  {
    JSON.create_id => self.class.name,
    'a'            => to_a,
  }
end

Методы Set#as_json и Set.json_create можно использовать для сериализации и десериализации объекта Set; см. Marshal.

Метод Set#as_json сериализует self и возвращает хеш из двух элементов, представляющий self:

require 'json/add/set'
x = Set.new(%w/foo bar baz/).as_json
# => {"json_class"=>"Set", "a"=>["foo", "bar", "baz"]}

Метод JSON.create десериализует такой хеш и возвращает объект Set:

Set.json_create(x) # => #<Set: {"foo", "bar", "baz"}>
classify { |o| ... } → hash Показать исходный код
classify → enumerator
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];
}

Классифицирует множество по возвращаемому заданным блоком значению и возвращает хеш пар {значение => множество элементов}. Блок вызывается один раз для каждого элемента множества, которому передаётся этот элемент.

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"]}

Если блок не задан, возвращает перечислитель.

clear → self Показать исходный код
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_table_clear(RSET_TABLE(set));
        set_compact_after_delete(set);
    }
    return set;
}

Удаляет все элементы и возвращает self.

set = Set[1, 'c', :s]             #=> Set[1, "c", :s]
set.clear                         #=> Set[]
set                               #=> Set[]
collect! { |o| ... } → self Показать исходный код
collect! → enumerator
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;
}

Заменяет элементы значениями, возвращёнными collect. Если блок не задан, возвращает перечислитель.

Также имеет псевдоним: map!
compare_by_identity → self Показать исходный код
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);
}

Заставляет множество сравнивать элементы по их идентичности и возвращает self.

compare_by_identity? → true or false Показать исходный код
static VALUE
set_i_compare_by_identity_p(VALUE set)
{
    return RBOOL(RSET_COMPARE_BY_IDENTITY(set));
}

Возвращает true, если множество сравнивает элементы по их идентичности. См. также Set#compare_by_identity.

delete(obj) → self Показать исходный код
static VALUE
set_i_delete(VALUE set, VALUE item)
{
    rb_check_frozen(set);
    if (set_table_delete(RSET_TABLE(set), (st_data_t *)&item)) {
        set_compact_after_delete(set);
    }
    return set;
}

Удаляет заданный объект из множества и возвращает self. Чтобы удалить сразу несколько элементов, используйте subtract.

delete?(obj) → self or nil Показать исходный код
static VALUE
set_i_delete_p(VALUE set, VALUE item)
{
    rb_check_frozen(set);
    if (set_table_delete(RSET_TABLE(set), (st_data_t *)&item)) {
        set_compact_after_delete(set);
        return set;
    }
    return Qnil;
}

Удаляет заданный объект из множества и возвращает self. Если объекта нет в множестве, возвращает nil.

delete_if { |o| ... } → self Показать исходный код
delete_if → enumerator
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;
}

Удаляет каждый элемент множества, для которого блок возвращает true, и возвращает self. Если блок не задан, возвращает перечислитель.

difference
Псевдоним для: -
disjoint?(set) → true or false Показать исходный код
static VALUE
set_i_disjoint(VALUE set, VALUE other)
{
    return RBOOL(!RTEST(set_i_intersect(set, other)));
}

Возвращает true, если у этого множества и заданного перечислимого объекта нет общих элементов. Этот метод противоположен 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
divide { |o1, o2| ... } → set Показать исходный код
divide { |o| ... } → set
divide → enumerator
static VALUE
set_i_divide(VALUE set)
{
    RETURN_SIZED_ENUMERATOR(set, 0, 0, set_enum_size);

    if (rb_block_arity() == 2) {
        return set_divide_arity2(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;
}

Разбивает множество на набор подмножеств согласно общности, определяемой заданным блоком.

Если арность блока равна 2, элементы o1 и o2 считаются общими, когда и block.call(o1, o2), и block.call(o2, o1) возвращают true. В противном случае элементы o1 и o2 считаются общими, когда 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]]

Если блок не задан, возвращает перечислитель.

each { |o| ... } → self Показать исходный код
each → enumerator
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;
}

Вызывает заданный блок один раз для каждого элемента множества, передавая ему этот элемент. Если блок не задан, возвращает перечислитель.

empty? → true or false Показать исходный код
static VALUE
set_i_empty(VALUE set)
{
    return RBOOL(RSET_EMPTY(set));
}

Возвращает true, если множество не содержит элементов.

encode_with (coder) Показать исходный код
# File ext/psych/lib/psych/core_ext.rb, line 23
def encode_with(coder)
  hash = {}
  each do |m|
    hash[m] = true
  end
  coder["hash"] = hash
  coder
end
eql?
Псевдоним для: ==
filter!
Псевдоним для: select!
flatten → set Показать исходный код
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 Показать исходный код
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));
}

Эквивалентен Set#flatten, но заменяет получателем себя на месте результатом операции. Возвращает nil, если изменений не было.

hash → integer Показать исходный код
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);
}

Возвращает хеш-код множества.

include?(item) → true or false Показать исходный код
static VALUE
set_i_include(VALUE set, VALUE item)
{
    return RBOOL(RSET_IS_MEMBER(set, item));
}

Возвращает true, если множество содержит заданный объект:

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

Обратите внимание, что include? и member? проверяют равенство элементов не с помощью ==, как это делают другие перечислимые объекты.

Этот метод имеет псевдоним ===, поэтому его можно использовать в выражениях case:

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

См. также Enumerable#include?

Также имеет псевдонимы: member?, ===
init_with (coder) Показать исходный код
# File ext/psych/lib/psych/core_ext.rb, line 32
def init_with(coder)
  replace(coder["hash"].keys)
end
inspect → new_string Показать исходный код
static VALUE
set_i_inspect(VALUE set)
{
    return rb_exec_recursive(set_inspect, set, 0);
}

Возвращает новую строку, содержащую элементы множества:

s = Set.new
s.inspect # => "Set[]"
s.add(1)
s.inspect # => "Set[1]"
s.add(2)
s.inspect # => "Set[1, 2]"

Связанный раздел: см. Методы преобразования.

Также имеет псевдоним: to_s
intersect?(set) → true or false Показать исходный код
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");
    }
}

Возвращает true, если у этого множества и заданного перечислимого объекта есть хотя бы один общий элемент.

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
intersection
Псевдоним для: &
join(separator=nil)→ new_string Показать исходный код
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_if → enumerator
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;
}

Удаляет каждый элемент множества, для которого блок возвращает false, и возвращает self. Если блок не задан, возвращает перечислитель.

length
Псевдоним для: size
map!
Псевдоним для: collect!
member?
Псевдоним для: include?
merge(*enums, **nil) → self Показать исходный код
static VALUE
set_i_merge(int argc, VALUE *argv, VALUE set)
{
    if (rb_keyword_given_p()) {
        rb_raise(rb_eArgError, "no keywords accepted");
    }

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

    rb_check_frozen(set);

    int i;

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

    return set;
}

Объединяет элементы заданных перечислимых объектов с множеством и возвращает self.

proper_subset?(set) → true or false Показать исходный код
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);
}

Возвращает true, если это множество является собственным подмножеством заданного множества.

Также имеет псевдоним: <
proper_superset?(set) → true or false Показать исходный код
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);
}

Возвращает true, если это множество является собственным надмножеством заданного множества.

Также имеет псевдоним: >
reject! { |o| ... } → self Показать исходный код
reject! → enumerator
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;
}

Эквивалентен Set#delete_if, но возвращает nil, если изменений не было. Если блок не задан, возвращает перечислитель.

replace(enum) → self Показать исходный код
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_table_clear(RSET_TABLE(set));
        set_merge_enum_into(set, other);
    }

    return set;
}

Заменяет содержимое множества содержимым заданного перечислимого объекта и возвращает self.

set = Set[1, 'c', :s]             #=> Set[1, "c", :s]
set.replace([1, 2])               #=> Set[1, 2]
set                               #=> Set[1, 2]
reset → self Показать исходный код
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);
}

Сбрасывает внутреннее состояние после изменения существующих элементов и возвращает self. Элементы будут проиндексированы заново, а дубликаты удалены.

select! { |o| ... } → self Показать исходный код
select! → enumerator
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;
}

Эквивалентен Set#keep_if, но возвращает nil, если изменений не было. Если блок не задан, возвращает перечислитель.

Также имеет псевдоним: filter!
size → integer Показать исходный код
static VALUE
set_i_size(VALUE set)
{
    return RSET_SIZE_NUM(set);
}

Возвращает количество элементов.

Также имеет псевдоним: length
subset?(set) → true or false Показать исходный код
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);
}

Возвращает true, если это множество является подмножеством заданного множества.

Также имеет псевдоним: <=
subtract(enum) → self Показать исходный код
static VALUE
set_i_subtract(VALUE set, VALUE other)
{
    rb_check_frozen(set);
    set_remove_enum_from(set, other);
    return set;
}

Удаляет каждый элемент, встречающийся в заданном перечислимом объекте, и возвращает self.

superset?(set) → true or false Показать исходный код
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);
}

Возвращает true, если множество является надмножеством заданного множества.

Также имеет псевдоним: >=
to_a → array Показать исходный код
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;
}

Возвращает массив, содержащий все элементы множества.

Set[1, 2].to_a                    #=> [1, 2]
Set[1, 'c', :s].to_a              #=> [1, "c", :s]
to_json (*args) Показать исходный код
# File ext/json/lib/json/add/set.rb, line 44
def to_json(*args)
  as_json.to_json(*args)
end

Возвращает строку JSON, представляющую self:

require 'json/add/set'
puts Set.new(%w/foo bar baz/).to_json

Вывод:

{"json_class":"Set","a":["foo","bar","baz"]}
to_s
Псевдоним для: inspect
to_set(klass = Set, *args, &block) → self or new_set Показать исходный код
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 {
        rb_warn_deprecated("passing arguments to Set#to_set", NULL);
        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);
}

Без аргументов возвращает self (для утиной типизации в методах, принимающих аргументы «множество или объект, преобразуемый в множество»).

Форма с аргументами устарела. Она преобразует множество в другое с помощью klass.new(self, *args, &block).

union
Псевдоним для: |

Ruby Core © 1993–2025 Yukihiro Matsumoto
Licensed under the Ruby License.
Ruby Standard Library © contributors
Licensed under their own licenses.

Spec-Zone.ru

Настройки Оффлайн Что нового Помощь О нас
Spec-Zone .ru
спецификации, руководства, описания, API