struct Pf::Set(T)

Overview

A thread-safe, persistent, unordered set.

See also: Map.

Included Modules

Defined in:

permafrost/set.cr

Constructors

Class Method Summary

Instance Method Summary

Instance methods inherited from module Enumerable(T)

to_pf_bidi to_pf_bidi, to_pf_map(& : T -> Tuple(K, V)) : Pf::Map(K, V) forall K, V
to_pf_map
to_pf_map
, to_pf_set : Pf::Set(T) to_pf_set

Constructor Detail

def self.additive_identity : self #

[View source]
def self.new(enumerable : Enumerable(T)) : Set(T) #

Returns a new set containing elements from enumerable.

set = Pf::Set.new([1, 2, 3])
set # => Pf::Set[1, 2, 3]

[View source]
def self.new : Set(T) #

Returns a new, empty set.

set = Pf::Set(Int32).new
set.empty? => true

[View source]

Class Method Detail

def self.[](*elements) #

Returns a new set with the given elements.

The type of the returned set is the union of the types of elements.

set = Pf::Set[1, "Hello", 3, true]
set # => Pf::Set[1, "Hello", 3, true]

typeof(set) # => Pf::Set(String | Int32 | Bool)

[View source]
def self.transaction(& : Commit(T) -> ) : Set(T) #

Shorthand for new.transaction.


[View source]

Instance Method Detail

def &(other : Set(T)) #

Returns a new set containing elements common to this and other sets.

a = Pf::Set[1, 2, 3]
b = Pf::Set[4, 5, 1, 6, 2]
a & b # => Pf::Set[1, 2]

[View source]
def +(other) : Set(T) #

Shorthand for #concat.


[View source]
def -(other : Set(T)) : Set(T) #

Returns a new set containing elements in this set that are not present in other.

Supports value equality.

Pf::Set[:a, :b, :c, :d] - Pf::Set[:a, :c] # => Pf::Set[:b, :d]

[View source]
def ==(other : Set) #

Returns true if the sets are equal.


[View source]
def ===(object : T) : Bool #

Same as Set#===.

reds = Pf::Set["red", "pink", "violet"]
blues = Pf::Set["blue", "azure", "violet"]

both = red = blue = false

case "violet"
when reds & blues
  both = true
when reds
  red = true
when blues
  blue = true
end

both # => true
red  # => false
blue # => false

[View source]
def add(element : T) : Set(T) #

Returns a copy of this set that includes element.

Supports value equality.

set = Pf::Set[100, 200]
set.add(300) # => Pf::Set[100, 200, 300]
set.add(400) # => Pf::Set[100, 200, 400]

[View source]
def concat(other : Enumerable(T)) : Set(T) #

Returns a copy of this set that also includes elements from other enumerable.

Supports value equality.

a = Pf::Set[1, 2, 3]
a.concat([4, 5, 1, 2]) # => Pf::Set[1, 2, 3, 4, 5]

[View source]
def delete(element : T) : Set(T) #

Returns a copy of this set that is guaranteed not to include element.

Supports value equality.

set = Pf::Set[100, 200, 300]
set.delete(100) # => Pf::Set[200, 300]
set.delete(200) # => Pf::Set[100, 300]

[View source]
def each(& : T -> ) : Nil #

Yields each element from this set.


[View source]
def empty? : Bool #

Returns true if this set is empty.

set = Pf::Set(Int32).new
set.empty? # => true

newset = set.add(100)
newset.empty? # => false

[View source]
def fmap(& : T -> U) : Set(U) forall U #

Yields each element from this set to the block and constructs a new set from block return results.

Supports value equality if T == U.

There is no shortcut in terms of performance. Even if all elements produced by the block are already in this set, a new set is created and populated anyway. We do keep track of changes, and if none were made return self; the new set is then simply discarded.

set = Pf::Set[1, 2, 3]
set.fmap(&.succ.to_s)            # => Pf::Set["2", "3", "4"]
set.fmap(&.succ.pred).same?(set) # => true

[View source]
def hash(hasher) #

See Object#hash(hasher).


[View source]
def includes?(element : T) : Bool #

Returns true if element is present in this set.

set = Pf::Set[1, 2, 3]

1.in?(set)        # => true
2.in?(set)        # => true
3.in?(set)        # => true
100.in?(set)      # => false
"foobar".in?(set) # => false

[View source]
def inspect(io : IO) : Nil #

Alias of #to_s.


[View source]
def pretty_print(pp) : Nil #

[View source]
def reject(& : T -> ) : Set(T) #

Returns a new set that includes only elements for which the block is falsey.

Supports value equality.

set = (0...10).to_pf_set
set.reject(&.even?) # => Pf::Set[1, 3, 5, 7, 9]

[View source]
def same?(other : Set(T)) #

Returns true if self and other refer to the same set in memory.

Due to the way Set is implemented, this method can be used as a cheap way to detect changes.

set1 = Pf::Set[1, 2, 3]
set2 = set1.add(1).add(2).add(3)
set1.same?(set2) # => true

[View source]
def select(& : T -> ) : Set(T) #

Returns a new set that includes only elements for which the block is truthy.

Supports value equality.

set = (0...10).to_pf_set
set.select(&.even?) # => Pf::Set[0, 2, 4, 6, 8]

[View source]
def size : Int32 #

Returns the number of elements in this set.

set = Pf::Set[1, 5]
set.size # => 2

[View source]
def to_s(io) #

[View source]
def transaction(& : Commit(T) -> ) : Set(T) #

Yields a Commit object which you can populate by multiple edits of this set. Applies the commit to a copy of this set. Returns the copy.

  • The commit object is marked as resolved after the block. You should not retain it. If you do, all operations on the object (including readonly ones) will raise ResolvedError.

  • If you pass the commit object to another fiber in the block, e.g. via a channel, and fiber yield immediately after that, the commit obviously would not be marked as resolved as the resolution code would not have been reached yet. However, if you then attempt to call mutation methods on the commit, another error, ReadonlyError, will be raised. In other words, the yielded commit object is readonly for any other fiber except for the fiber that it was originally yielded to.

Returns self if the transaction did not touch the set. If the set was changed but then the changes were reverted this method will return a new set (one equal to self).

set1 = Pf::Set[1, 2, 3]
set2 = set1.transaction do |commit|
  commit.add(4)
  commit.delete(2) if 4.in?(commit)
  if 2.in?(commit)
    commit.delete(4)
    commit.add(6)
  else
    commit.delete(4)
    commit.add(2)
    commit.add(5)
  end
end

set1 # => Pf::Set[1, 2, 3]
set2 # => Pf::Set[1, 2, 3, 5]

[View source]