首页
学习
活动
专区
工具
TVP
发布
精选内容/技术社群/优惠产品,尽在小程序
立即前往

Set

Parent:ObjectIncluded modules:Enumerable

Set实现无重复值的集合。这是Array的直观互操作设施和Hash快速查找的混合体。

Set可以很容易地与Enumerable对象一起使用(实现每个对象)。 大多数初始化方法和二元运算符接受除了集合和数组之外的泛型Enumerable对象。 Enumerable对象可以使用to_set方法转换为Set。

设置使用哈希作为存储,所以你必须注意以下几点:

  • 元素的等值是根据Object#eql确定的。和Object#hash。使用#compare_by_identity使一组数据按其身份进行比较。
  • Set假定每个元素的标识在存储时不会改变。修改集合中的一个元素会使集合处于不可靠状态。
  • 当要存储字符串时,将存储字符串的冻结副本,除非原始字符串已冻结。

对照

比较运算符<,>,<=和> =被实现为{proper _,} {subset?,superset?}方法的简写形式。然而,<=>操作符被故意排除,因为不是每一对集合都是可比的。({x,y}对比{x,z}))

代码语言:javascript
复制
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

公共类方法

显示来源

创建一个包含给定对象的新集合。

代码语言:javascript
复制
# File lib/set.rb, line 74
def self.[](*ary)
  new(ary)
end

new(enum = nil) { |o| ... } Show source

创建一个包含给定枚举对象的元素的新集合。

如果给出了一个块,枚举的元素由给定的块进行预处理。

代码语言:javascript
复制
# 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

公共实例方法

&(enum) Show source

返回一个新集合,其中包含该集合和给定可枚举对象共有的元素。

代码语言:javascript
复制
# 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

另外别名为: intersection

+(enum)

别名:|

-(enum) Show source

返回通过复制集合构建的新集合,删除给定可枚举对象中出现的每个元素。

代码语言:javascript
复制
# File lib/set.rb, line 432
def -(enum)
  dup.subtract(enum)
end

还有别名:difference

<(set)

别名为:proper_subset?

<<(o)

别名为:add

<=(set)

别名为:subset?

==(other) Show source

如果两组相等,则返回true。每对元素的相等性根据Object#eql?定义。

代码语言:javascript
复制
# 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

(set)

别名为:proper_superset?

=(set)

别名为:superset?

^(enum) Show source

返回包含集合与给定枚举对象之间排他性元素的新集合。(set ^ enum)相当于((set | enum) - (set&enum))。

代码语言:javascript
复制
# File lib/set.rb, line 449
def ^(enum)
  n = Set.new(enum)
  each { |o| n.add(o) unless n.delete?(o) }
  n
end

add(o) Show source

将给定对象添加到该集合并返回自身。 使用merge一次添加许多元素。

代码语言:javascript
复制
# File lib/set.rb, line 330
def add(o)
  @hash[o] = true
  self
end

另外别名为:<<

add?(o) Show source

将给定对象添加到该集合并返回自身。如果该对象已经在该集合中,则返回nil。

代码语言:javascript
复制
# File lib/set.rb, line 338
def add?(o)
  add(o) unless include?(o)
end

classify() { |o| ... } Show source

通过给定块的返回值对集合进行分类,并返回{value =>元素集}对的散列。对于该集合的每个元素,该块将被调用一次,并将该元素作为参数传递。

例如:

代码语言:javascript
复制
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"}>}

如果没有给出块,则返回一个枚举器。

代码语言:javascript
复制
# 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

clear() Show source

删除所有元素并返回自身。

代码语言:javascript
复制
# File lib/set.rb, line 162
def clear
  @hash.clear
  self
end

collect!() { |o| ... } Show source

用collect()返回的元素替换元素。如果没有给出块,则返回一个枚举器。

代码语言:javascript
复制
# 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

另外别名为:map!

compare_by_identity() Show source

使集合通过他们的身份比较其元素并返回自身。Set的所有子类都可能不支持此方法。

代码语言:javascript
复制
# 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

compare_by_identity?() Show source

如果该集合将按其身份比较其元素,则返回true。另请参阅#compare_by_identity。

代码语言:javascript
复制
# File lib/set.rb, line 108
def compare_by_identity?
  @hash.respond_to?(:compare_by_identity?) && @hash.compare_by_identity?
end

delete(o) Show source

从集合中删除给定的对象并返回自身。用subtract一次删除多个项目。

代码语言:javascript
复制
# File lib/set.rb, line 344
def delete(o)
  @hash.delete(o)
  self
end

delete?(o) Show source

从集合中删除给定的对象并返回自身。如果该对象不在该集合中,则返回nil。

代码语言:javascript
复制
# File lib/set.rb, line 351
def delete?(o)
  delete(o) if include?(o)
end

delete_if() { |o| ... } Show source

删除块评估为true的集合中的每个元素,并返回自身。如果没有给出块,则返回一个枚举器。

代码语言:javascript
复制
# 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

difference(enum)

别名: -

disjoint?(set) Show source

如果集合和给定集合没有共同的元素,则返回true。这种方法与intersect?相反。

例如:

代码语言:javascript
复制
require 'set'
Set[1, 2, 3].disjoint? Set[3, 4] # => false
Set[1, 2, 3].disjoint? Set[4, 5] # => true
代码语言:javascript
复制
# File lib/set.rb, line 315
def disjoint?(set)
  !intersect?(set)
end

divide(&func) Show source

根据给定块定义的通用性将集合划分为一组子集。

如果block的arity是2,如果block.call(o1,o2)为true,则元素o1和o2是相同的。否则,如果block.call(o1)== block.call(o2),元素o1和o2是相同的。

例如:

代码语言:javascript
复制
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}>}>

如果没有给出块,则返回一个枚举器。

代码语言:javascript
复制
# 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

each(&block) Show source

为集合中的每个元素调用一次给定的块,将元素作为参数传递。如果没有给出块,则返回一个枚举器。

代码语言:javascript
复制
# File lib/set.rb, line 322
def each(&block)
  block or return enum_for(__method__) { size }
  @hash.each_key(&block)
  self
end

empty?() Show source

如果该集合不包含任何元素,则返回true。

代码语言:javascript
复制
# File lib/set.rb, line 157
def empty?
  @hash.empty?
end

flatten() Show source

返回一个新集合,该集合是该集合的一个副本,递归地展平每个包含集合的集合。

代码语言:javascript
复制
# File lib/set.rb, line 216
def flatten
  self.class.new.flatten_merge(self)
end

flatten!() Show source

等同于#flatten,但用适当的结果代替接收器。如果没有修改,返回nil。

代码语言:javascript
复制
# File lib/set.rb, line 222
def flatten!
  replace(flatten()) if any? { |e| e.is_a?(Set) }
end

include?(o) Show source

如果集合包含给定的对象,则返回true。

请注意,包括include?member? 不要像使用其他Enumerables一样使用==测试成员相等性。

另请参阅Enumerable #include?

代码语言:javascript
复制
# File lib/set.rb, line 232
def include?(o)
  @hash[o]
end

另外别名为:成员?

initialize_clone(orig) Show source

克隆内部哈希。

调用超类方法

代码语言:javascript
复制
# File lib/set.rb, line 130
def initialize_clone(orig)
  super
  @hash = orig.instance_variable_get(:@hash).clone
end

initialize_dup(orig) Show source

Dup 内部哈希。

调用超类方法

代码语言:javascript
复制
# File lib/set.rb, line 124
def initialize_dup(orig)
  super
  @hash = orig.instance_variable_get(:@hash).dup
end

inspect() Show source

返回包含该集合的人类可读表示的字符串。(“#<Set:{element1,element2,...}>”)

代码语言:javascript
复制
# 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

intersect?(set) Show source

如果集合和给定集合至少有一个共同元素,则返回true。

例如:

代码语言:javascript
复制
require 'set'
Set[1, 2, 3].intersect? Set[4, 5] # => false
Set[1, 2, 3].intersect? Set[3, 4] # => true
代码语言:javascript
复制
# 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

intersection(enum)

别名为:

keep_if() { |o| ... } Show source

删除块评估为false的集合中的每个元素,并返回自身。如果没有给出块,则返回一个枚举器。

代码语言:javascript
复制
# 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

length()

别名为:size

map!()

别名为:collect!

member?(o)

别名为:include?

merge(enum) Show source

将给定枚举对象的元素合并到集合,并返回自身。

代码语言:javascript
复制
# 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

proper_subset?(set) Show source

如果集合是给定集合的适当子集,则返回true。

代码语言:javascript
复制
# 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

另外别名为:<

proper_superset?(set) Show source

如果该集合是给定集合的适当超集,则返回true。

代码语言:javascript
复制
# 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

另外别名为:>

reject!(&block) Show source

等同于#delete_if,但如果没有更改,则返回nil。如果没有给出块,则返回一个枚举器。

代码语言:javascript
复制
# 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

replace(enum) Show source

用给定枚举对象的内容替换集合的内容,并返回自身。

代码语言:javascript
复制
# 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

select!(&block) Show source

相当于#keep_if,但如果没有更改,则返回nil。如果没有给出块,则返回一个枚举器。

代码语言:javascript
复制
# 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

size() Show source

返回元素的数量。

代码语言:javascript
复制
# File lib/set.rb, line 151
def size
  @hash.size
end

另外别名为:长度

subset?(set) Show source

如果集合是给定集合的子集,则返回true。

代码语言:javascript
复制
# 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

另外别名为:<=

subtract(enum) Show source

删除给定可枚举对象中出现的每个元素并返回自身。

代码语言:javascript
复制
# File lib/set.rb, line 417
def subtract(enum)
  do_with_enum(enum) { |o| delete(o) }
  self
end

superset?(set) Show source

如果集合是给定集合的超集,则返回true。

代码语言:javascript
复制
# 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

另外别名为:> =

to_a() Show source

将集合转换为数组。元素的顺序是不确定的。

代码语言:javascript
复制
# File lib/set.rb, line 181
def to_a
  @hash.keys
end

to_set(klass = Set, *args, &block) Show source

如果没有给出参数,则返回自身。否则,使用klass.new(self,* args,&block)将该集合转换为另一个集合。

在子类中,返回klass.new(self,* args,&block),除非被覆盖。

代码语言:javascript
复制
# 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

union(enum)

别名:|

|(enum) Show source

返回通过合并集合和给定枚举对象的元素构建的新集合。

代码语言:javascript
复制
# File lib/set.rb, line 424
def |(enum)
  dup.merge(enum)
end

还有别名:+,union

扫码关注腾讯云开发者

领取腾讯云代金券

http://www.vxiaotou.com