Spec-Zone.ru › Ruby 2.4

класс Set

Родитель:
Объект
Включенные модули:
Enumerable

Множество реализует коллекцию неупорядоченных значений без дубликатов. Это гибрид интуитивных средств взаимодействия массива и быстрого поиска хэша.

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

Множество использует Хэш в качестве хранилища, поэтому необходимо учитывать следующие моменты:

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

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

  • Если строка должна быть сохранена, вместо неё хранится замороженная копия строки, если только исходная строка не заморожена.

Сравнение

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

Пример

require 'set'
s1 = Set.new [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> (current maintainer)

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

[](*ary) Показать исходный код
# File lib/set.rb, line 74
def self.[](*ary)
  new(ary)
end

Создаёт новое множество, содержащее заданные объекты.

new(enum = nil) { |o| ... } Показать исходный код
# File lib/set.rb, line 83
def initialize(enum = nil, &block) # :yields: o
  @hash ||= Hash.new(false)

  enum.nil? and return

  if block
    do_with_enum(enum) { |o| add(block[o]) }
  else
    merge(enum)
  end
end

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

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

Методы публичного экземпляра

&(enum) Показать исходный код
# File lib/set.rb, line 439
def &(enum)
  n = self.class.new
  do_with_enum(enum) { |o| n.add(o) if include?(o) }
  n
end

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

Также алиасируется как: пересечение
+(enum)
Псевдоним для: |
-(enum) Показать исходный код
# File lib/set.rb, line 432
def -(enum)
  dup.subtract(enum)
end

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

Также алиасируется как: разность
<(set)
Псевдоним для: собственно_подмножество?
<<(o)
Псевдоним для: добавить
<=(set)
Псевдоним для: подмножество?
==(other) Показать исходный код
# File lib/set.rb, line 457
def ==(other)
  if self.equal?(other)
    true
  elsif other.instance_of?(self.class)
    @hash == other.instance_variable_get(:@hash)
  elsif other.is_a?(Set) && self.size == other.size
    other.all? { |o| @hash.include?(o) }
  else
    false
  end
end

Возвращает true, если два набора равны. Равенство каждой пары элементов определяется в соответствии с Object#eql?.

>(set)
Псевдоним для: собственно_надмножество?
>=(set)
Псевдоним для: надмножество?
^(enum) Показать исходный код
# File lib/set.rb, line 449
def ^(enum)
  n = Set.new(enum)
  each { |o| n.add(o) unless n.delete?(o) }
  n
end

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

добавить(o) Показать исходный код
# File lib/set.rb, line 330
def add(o)
  @hash[o] = true
  self
end

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

Также алиасируется как: <<
добавить?(o) Показать исходный код
# File lib/set.rb, line 338
def add?(o)
  add(o) unless include?(o)
end

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

классифицировать() { |o| ... } Показать исходный код
# File lib/set.rb, line 493
def classify # :yields: o
  block_given? or return enum_for(__method__) { size }

  h = {}

  each { |i|
    (h[yield(i)] ||= self.class.new).add(i)
  }

  h
end

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

Например:

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

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

очистить() Показать исходный код
# File lib/set.rb, line 162
def clear
  @hash.clear
  self
end

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

собрать!() { |o| ... } Показать исходный код
# File lib/set.rb, line 379
def collect!
  block_given? or return enum_for(__method__) { size }
  replace(self.class.new(self) { |o| yield(o) })
end

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

Также алиасируется как: отобразить!
сравнить_по_идентичности() Показать исходный код
# File lib/set.rb, line 97
def compare_by_identity
  if @hash.respond_to?(:compare_by_identity)
    @hash.compare_by_identity
    self
  else
    raise NotImplementedError, "#{self.class.name}\##{__method__} is not implemented"
  end
end

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

сравнить_по_идентичности?() Показать исходный код
# File lib/set.rb, line 108
def compare_by_identity?
  @hash.respond_to?(:compare_by_identity?) && @hash.compare_by_identity?
end

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

удалить(o) Показать исходный код
# File lib/set.rb, line 344
def delete(o)
  @hash.delete(o)
  self
end

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

удалить?(o) Показать исходный код
# File lib/set.rb, line 351
def delete?(o)
  delete(o) if include?(o)
end

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

удалить_если() { |o| ... } Показать исходный код
# File lib/set.rb, line 358
def delete_if
  block_given? or return enum_for(__method__) { size }
  # @hash.delete_if should be faster, but using it breaks the order
  # of enumeration in subclasses.
  select { |o| yield o }.each { |o| @hash.delete(o) }
  self
end

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

разность(enum)
Псевдоним для: -
разнесённые?(set) Показать исходный код
# File lib/set.rb, line 315
def disjoint?(set)
  !intersect?(set)
end

Возвращает true, если набор и заданный набор не имеют общих элементов. Этот метод является обратным к intersect?.

Например:

require 'set'
Set[1, 2, 3].disjoint? Set[3, 4] # => false
Set[1, 2, 3].disjoint? Set[4, 5] # => true
разделить(&func) Показать исходный код
# File lib/set.rb, line 523
def divide(&func)
  func or return enum_for(__method__) { size }

  if func.arity == 2
    require 'tsort'

    class << dig = {}         # :nodoc:
      include TSort

      alias tsort_each_node each_key
      def tsort_each_child(node, &block)
        fetch(node).each(&block)
      end
    end

    each { |u|
      dig[u] = a = []
      each{ |v| func.call(u, v) and a << v }
    }

    set = Set.new()
    dig.each_strongly_connected_component { |css|
      set.add(self.class.new(css))
    }
    set
  else
    Set.new(classify(&func).values)
  end
end

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

Если арность блока равна 2, элементы o1 и o2 являются общими, если блок.call(o1, o2) равен true. В противном случае, элементы o1 и o2 являются общими, если блок.call(o1) == блок.call(o2).

Например:

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

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

каждый(&block) Показать исходный код
# File lib/set.rb, line 322
def each(&block)
  block or return enum_for(__method__) { size }
  @hash.each_key(&block)
  self
end

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

пустой?() Показать исходный код
# File lib/set.rb, line 157
def empty?
  @hash.empty?
end

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

сгладить() Показать исходный код
# File lib/set.rb, line 216
def flatten
  self.class.new.flatten_merge(self)
end

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

flatten!() Показать исходный код
# File lib/set.rb, line 222
def flatten!
  replace(flatten()) if any? { |e| e.is_a?(Set) }
end

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

include?(o) Показать исходный код
# File lib/set.rb, line 232
def include?(o)
  @hash[o]
end

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

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

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

Также алиасировано как: member?
initialize_clone(orig) Показать исходный код
# File lib/set.rb, line 130
def initialize_clone(orig)
  super
  @hash = orig.instance_variable_get(:@hash).clone
end

Клонирование внутренней хеш-таблицы.

Вызывает метод суперкласса
initialize_dup(orig) Показать исходный код
# File lib/set.rb, line 124
def initialize_dup(orig)
  super
  @hash = orig.instance_variable_get(:@hash).dup
end

Дублирование внутренней хеш-таблицы.

Вызывает метод суперкласса
inspect() Показать исходный код
# File lib/set.rb, line 557
def inspect
  ids = (Thread.current[InspectKey] ||= [])

  if ids.include?(object_id)
    return sprintf('#<%s: {...}>', self.class.name)
  end

  ids << object_id
  begin
    return sprintf('#<%s: {%s}>', self.class, to_a.inspect[1..-2])
  ensure
    ids.pop
  end
end

Возвращает строку, содержащую удобочитаемое представление множества. (“#<Set: {элемент1, элемент2, …}>”)

intersect?(set) Показать исходный код
# File lib/set.rb, line 297
def intersect?(set)
  set.is_a?(Set) or raise ArgumentError, "value must be a set"
  if size < set.size
    any? { |o| set.include?(o) }
  else
    set.any? { |o| include?(o) }
  end
end

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

Например:

require 'set'
Set[1, 2, 3].intersect? Set[4, 5] # => false
Set[1, 2, 3].intersect? Set[3, 4] # => true
intersection(enum)
Псевдоним для: &
keep_if() { |o| ... } Показать исходный код
# File lib/set.rb, line 369
def keep_if
  block_given? or return enum_for(__method__) { size }
  # @hash.keep_if should be faster, but using it breaks the order of
  # enumeration in subclasses.
  reject { |o| yield o }.each { |o| @hash.delete(o) }
  self
end

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

length()
Псевдоним для: size
map!()
Псевдоним для: collect!
member?(o)
Псевдоним для: include?
merge(enum) Показать исходный код
# File lib/set.rb, line 405
def merge(enum)
  if enum.instance_of?(self.class)
    @hash.update(enum.instance_variable_get(:@hash))
  else
    do_with_enum(enum) { |o| add(o) }
  end

  self
end

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

proper_subset?(set) Показать исходный код
# File lib/set.rb, line 277
def proper_subset?(set)
  case
  when set.instance_of?(self.class)
    @hash < set.instance_variable_get(:@hash)
  when set.is_a?(Set)
    size < set.size && all? { |o| set.include?(o) }
  else
    raise ArgumentError, "value must be a set"
  end
end

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

Также алиасировано как: <
proper_superset?(set) Показать исходный код
# File lib/set.rb, line 251
def proper_superset?(set)
  case
  when set.instance_of?(self.class)
    @hash > set.instance_variable_get(:@hash)
  when set.is_a?(Set)
    size > set.size && set.all? { |o| include?(o) }
  else
    raise ArgumentError, "value must be a set"
  end
end

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

Также алиасировано как: >
reject!(&block) Показать исходный код
# File lib/set.rb, line 387
def reject!(&block)
  block or return enum_for(__method__) { size }
  n = size
  delete_if(&block)
  self if size != n
end

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

replace(enum) Показать исходный код
# File lib/set.rb, line 169
def replace(enum)
  if enum.instance_of?(self.class)
    @hash.replace(enum.instance_variable_get(:@hash))
    self
  else
    do_with_enum(enum)  # make sure enum is enumerable before calling clear
    clear
    merge(enum)
  end
end

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

select!(&block) Показать исходный код
# File lib/set.rb, line 396
def select!(&block)
  block or return enum_for(__method__) { size }
  n = size
  keep_if(&block)
  self if size != n
end

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

size() Показать исходный код
# File lib/set.rb, line 151
def size
  @hash.size
end

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

Также алиасировано как: length
subset?(set) Показать исходный код
# File lib/set.rb, line 264
def subset?(set)
  case
  when set.instance_of?(self.class)
    @hash <= set.instance_variable_get(:@hash)
  when set.is_a?(Set)
    size <= set.size && all? { |o| set.include?(o) }
  else
    raise ArgumentError, "value must be a set"
  end
end

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

Также алиасировано как: <=
subtract(enum) Показать исходный код
# File lib/set.rb, line 417
def subtract(enum)
  do_with_enum(enum) { |o| delete(o) }
  self
end

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

superset?(set) Показать исходный код
# File lib/set.rb, line 238
def superset?(set)
  case
  when set.instance_of?(self.class)
    @hash >= set.instance_variable_get(:@hash)
  when set.is_a?(Set)
    size >= set.size && set.all? { |o| include?(o) }
  else
    raise ArgumentError, "value must be a set"
  end
end

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

Также алиасировано как: >=
to_a() Показать исходный код
# File lib/set.rb, line 181
def to_a
  @hash.keys
end

Преобразует множество в массив. Порядок элементов неопределён.

to_set(klass = Set, *args, &block) Показать исходный код
# File lib/set.rb, line 190
def to_set(klass = Set, *args, &block)
  return self if instance_of?(Set) && klass == Set && block.nil? && args.empty?
  klass.new(self, *args, &block)
end

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

В подклассах, возвращает klass.new(self, *args, █), если не переопределено.

union(enum)
Псевдоним для: |
|(enum) Показать исходный код
# File lib/set.rb, line 424
def |(enum)
  dup.merge(enum)
end

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

Также алиасировано как: +, union

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

Spec-Zone.ru

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