NAME
Sidef::Types::Set::Set - Unordered collection of unique elements supporting mathematical set operations.
DESCRIPTION
This class implements an unordered collection of unique elements. A Set automatically eliminates duplicate values and provides efficient membership testing. Sets support mathematical set operations like union, intersection, difference, and symmetric difference. It's a subclass of Sidef::Types::Hash::Hash: internally, each element is stored as a hash value, keyed by a string computed from the element itself.
Two elements are considered duplicates -- and so only one is kept -- if they produce the same key string. For an object with its own dump method (which covers essentially every built-in Sidef type), that dump string is the key, so e.g. two Number objects with the same numeric value are always deduplicated. For anything else (a raw, undumpable reference), Perl's own default stringification of the reference is used instead, which means two otherwise-identical-looking plain references are not considered equal unless they're the very same reference. nil is stored under the fixed key "nil".
A Set is also falsy, and numifies to 0, exactly when it's empty -- both its boolean and numeric conversions come from its element count.
SYNOPSIS
var a = Set(1, 2, 3, 4)
var b = Set(2, 3, 5)
say(a ^ b) #=> Set(1, 4, 5)
say(a - b) #=> Set(1, 4)
say(a | b) #=> Set(1, 2, 3, 4, 5)
say(a & b) #=> Set(2, 3)
say(a.has(2)) #=> true
say(a.len) #=> 4
say(b.map {|n| n**2 }) #=> Set(4, 9, 25)
say(b.grep {|n| n.is_odd }) #=> Set(3, 5)
INHERITS
Inherits methods from Sidef::Types::Hash::Hash.
CONSTRUCTION
new
Set(*elements)
Set.new(*elements)
Creates a new set containing elements (duplicates, per the rule described above, are silently merged into one). With no arguments, creates an empty set. Note that this constructor always blesses into the literal Sidef::Types::Set::Set package itself, regardless of the invocant -- it is not polymorphic, unlike most of the other methods below (such as "concat", which does respect subclasses).
var s1 = Set()
var s2 = Set(1, 2, 3)
var s3 = Set.new(1, 2, 2, 3) # duplicates merged: Set(1, 2, 3)
Aliases: call
SET ALGEBRA
For "union", "intersection", "difference", and "symmetric_difference", the right-hand operand doesn't have to already be a Set -- if it isn't one, it's first converted with .to_set (so an Array, a Range, and so on all work directly). "concat" (the + operator) is the one exception: see its entry below.
concat
self.concat(other)
self + other
If other is also a Set (of the exact same class), returns a new set combining every element of both -- equivalent to "union". If other is anything else, it is added as a single new element of the result, not merged element-by-element -- unlike "union" and the other set-algebra methods, other is not converted with .to_set first.
var a = Set(1, 2, 3)
var b = Set(4, 5, 6)
say(a + b) #=> Set(1, 2, 3, 4, 5, 6) # same-class merge
say(Set(1, 2, 3) + [4, 5, 6])
#=> Set(1, 2, 3, [4, 5, 6]) # the whole array added as ONE element
Aliases: operator +
union
self.union(other)
self | other
Returns a new set containing every element that appears in self or other (or both).
var a = Set(1, 2, 3)
var b = Set(3, 4, 5)
say(a | b) #=> Set(1, 2, 3, 4, 5)
Aliases: or, operator |, operator ∪
intersection
self.intersection(other)
self & other
Returns a new set containing only the elements present in both self and other.
var a = Set(1, 2, 3, 4)
var b = Set(3, 4, 5, 6)
say(a & b) #=> Set(3, 4)
Aliases: and, operator &, operator ∩
difference
self.difference(other)
self - other
Returns a new set containing the elements of self that are not present in other.
var a = Set(1, 2, 3, 4, 5)
var b = Set(3, 4, 5)
say(a - b) #=> Set(1, 2)
Aliases: sub, diff, operator -, operator ∖
symmetric_difference
self.symmetric_difference(other)
self ^ other
Returns a new set containing the elements that are in exactly one of self or other, but not both.
var a = Set(1, 2, 3, 4)
var b = Set(3, 4, 5, 6)
say(a ^ b) #=> Set(1, 2, 5, 6)
Aliases: xor, symdiff, operator ^
MEMBERSHIP AND COMPARISON
has
self.has(obj)
self ∋ obj
Returns true if obj (compared the same way as for deduplication -- see "DESCRIPTION") is an element of the set, otherwise false.
var s = Set(1, 2, 3)
say(s ∋ 2) #=> true
say(s ∋ 5) #=> false
Aliases: haskey, has_key, exists, include, includes, contain, contains, operator ∋
∌
self ∌ obj
Returns true if obj is not an element of the set -- the logical negation of "has".
var s = Set(1, 2, 3)
say(s ∌ 5) #=> true
say(s ∌ 2) #=> false
contains_all
self.contains_all(*objects)
Returns true if every one of objects is an element of the set, otherwise false.
var s = Set(1, 2, 3, 4, 5)
say(s.contains_all(1, 2, 3)) #=> true
say(s.contains_all(1, 2, 9)) #=> false
is_subset
self.is_subset(other)
self <= other
Returns true if every element of self is also in other (other is converted with .to_set first if it isn't already a set).
var a = Set(1, 2)
var b = Set(1, 2, 3, 4)
say(a <= b) #=> true
Aliases: operator <=, operator ≤, operator ⊆
is_superset
self.is_superset(other)
self >= other
Returns true if every element of other is also in self (other is converted with .to_set first if it isn't already a set).
var a = Set(1, 2, 3, 4)
var b = Set(1, 2)
say(a >= b) #=> true
Aliases: operator >=, operator ≥, operator ⊇
≡
self ≡ other
Returns true if self and other contain exactly the same elements (order never matters, since sets are unordered). This delegates directly to the inherited Hash equality check, rather than having its own Set-specific implementation.
var a = Set(1, 2, 3)
var b = Set(3, 2, 1)
var c = Set(1, 2, 4)
say(a ≡ b) #=> true
say(a ≡ c) #=> false
ADDING AND REMOVING ELEMENTS
append
self.append(*objects)
self << obj
Adds every one of objects to the set in-place (silently merging in place of any existing duplicate) and returns self.
var s = Set(1, 2, 3)
s << 4
say(s) #=> Set(1, 2, 3, 4)
Aliases: add, push, operator <<
delete
self.delete(*objects)
Removes every one of objects from the set, if present, and returns the removed value(s).
var s = Set(1, 2, 3, 4, 5)
s.delete(2, 4)
say(s) #=> Set(1, 3, 5)
Aliases: remove, discard
pop
self.pop
Removes and returns an arbitrary element from the set. Since a set has no defined order, this is not guaranteed to be any particular element -- it's whichever one happens to come last according to the underlying hash's own (unordered) key order. Behaves identically to "shift".
var s = Set(1, 2, 3)
s.pop
say(s.len) #=> 2
shift
self.shift
Removes and returns an arbitrary element from the set. As with "pop", since a set has no defined order, "first" here doesn't carry its usual array meaning -- pop and shift behave identically on a Set.
var s = Set(1, 2, 3)
s.shift
delete_if
self.delete_if(block)
Removes every element for which block returns a truthy value, and returns self.
var s = Set(1, 2, 3, 4, 5, 6)
s.delete_if {|n| n.is_even }
say(s) #=> Set(1, 3, 5)
delete_first_if
self.delete_first_if(block)
Removes only the first element (in the underlying hash's own unordered iteration order) for which block returns a truthy value, and returns self.
var s = Set(1, 2, 3, 4, 5)
s.delete_first_if {|n| n > 3 }
say(s.len) #=> 4
ITERATION
each
self.each(block)
Calls block once for every element in the set, and returns self.
var s = Set(1, 2, 3)
s.each {|n| say(n) }
each_2d
self.each_2d(block)
Iterates over a set whose elements are themselves array-like (e.g. pairs or tuples), spreading each element's own contents as separate arguments to block. This is not related to element position/index -- it simply dereferences each stored element as an array.
var pairs = Set([1, "a"], [2, "b"], [3, "c"])
pairs.each_2d {|k, v| say("#{k}: #{v}") }
iter
self.iter
Returns an iterator (a Block) over the set's elements (in the underlying hash's own unordered order). Call it with .run to get each successive element; it returns nil once exhausted.
var s = Set(1, 2, 3)
var it = s.iter
say(it.run) # some element of the set
say(it.run) # another element
TRANSFORMATION AND FILTERING
map
self.map(block)
Returns a new set with the result of calling block on each element (results are deduplicated, like any other set construction; if block returns more than one value for a given element, each of those values becomes its own element in the result). If block is omitted, elements are kept as-is.
var s = Set(1, 2, 3)
say(s.map {|n| n**2 }) #=> Set(1, 4, 9)
map_2d
self.map_2d(block)
Like "map", but for a set whose elements are themselves array-like -- each element's own contents are spread as separate arguments to block (rather than passing the whole element as one argument).
var pairs = Set([1, "a"], [2, "b"])
say(pairs.map_2d {|k, v| "#{k}:#{v}" })
collect
self.collect(block)
Calls block once per element and collects every result into an Array -- not a new Set. Unlike "map", results are kept in full (no deduplication), one per source element.
var s = Set(1, 2, 3)
say(s.collect {|n| n * 2 }) #=> [2, 4, 6] (an Array, order may vary)
grep
self.grep(block)
Returns a new set containing only the elements for which block returns a truthy value. If block is omitted, elements are kept based on their own truthiness.
var s = Set(1, 2, 3, 4, 5, 6)
say(s.grep {|n| n.is_even }) #=> Set(2, 4, 6)
Aliases: select
grep_2d
self.grep_2d(block)
Like "grep", but for a set whose elements are themselves array-like -- each element's own contents are spread as separate arguments to block.
var pairs = Set([10, "a"], [20, "b"], [5, "c"])
say(pairs.grep_2d {|n, label| n > 8 }) #=> Set([10, "a"], [20, "b"])
AGGREGATION AND PREDICATES
count
self.count(obj)
self.count(block)
If given a plain value, returns 1 if the set "has" it, or 0 otherwise (a set never contains duplicates, so this is a membership test rather than a general tally). If given a block, delegates entirely to "count_by".
var s = Set(1, 2, 3)
say(s.count(2)) #=> 1
say(s.count(5)) #=> 0
count_by
self.count_by(block)
Returns the number of elements for which block returns a truthy value. (This is a plain count, not a group-by tally -- it returns a single Number, the same thing count returns when it's given a block.)
var s = Set(1, 2, 3, 4, 5, 6)
say(s.count_by {|n| n.is_even }) #=> 3
sum
self.sum(block)
Returns the sum of all elements, or the sum of block applied to each element if given.
var s = Set(1, 2, 3, 4)
say(s.sum) #=> 10
say(s.sum {|n| n**2 }) #=> 30
Aliases: sum_by
sum_2d
self.sum_2d(block)
Like "sum", but for a set whose elements are themselves array-like -- each element's own contents are spread as separate arguments to block.
var pairs = Set([1, 10], [2, 20])
say(pairs.sum_2d {|a, b| a + b }) #=> 33 # (1+10) + (2+20)
prod
self.prod(block)
Returns the product of all elements, or the product of block applied to each element if given.
var s = Set(2, 3, 4)
say(s.prod) #=> 24
say(s.prod {|n| n**2 }) #=> 576
Aliases: prod_by
prod_2d
self.prod_2d(block)
Like "prod", but for a set whose elements are themselves array-like -- each element's own contents are spread as separate arguments to block.
var pairs = Set([1, 10], [2, 20])
say(pairs.prod_2d {|a, b| a + b }) #=> 242 # (1+10) * (2+20)
min
self.min
Returns the minimum element of the set.
var s = Set(5, 2, 8, 1, 9)
say(s.min) #=> 1
min_by
self.min_by(block)
Returns the element for which block returns the smallest value.
var s = Set(-5, 3, -10, 7)
say(s.min_by {|n| n.abs }) #=> 3
max
self.max
Returns the maximum element of the set.
var s = Set(5, 2, 8, 1, 9)
say(s.max) #=> 9
max_by
self.max_by(block)
Returns the element for which block returns the largest value.
var s = Set(-5, 3, -10, 7)
say(s.max_by {|n| n.abs }) #=> -10
all
self.all(block)
Returns true if block is truthy for every element in the set. If block is omitted, elements are tested for their own truthiness.
var s = Set(2, 4, 6, 8)
say(s.all {|n| n.is_even }) #=> true
say(s.all {|n| n > 5 }) #=> false
any
self.any(block)
Returns true if block is truthy for at least one element in the set. If block is omitted, elements are tested for their own truthiness.
var s = Set(1, 2, 3, 4)
say(s.any {|n| n > 3 }) #=> true
say(s.any {|n| n > 10 }) #=> false
none
self.none(block)
Returns true if block is falsy for every element in the set. If block is omitted, elements are tested for their own truthiness.
var s = Set(1, 3, 5, 7)
say(s.none {|n| n.is_even }) #=> true
say(s.none {|n| n > 5 }) #=> false
SORTING AND CONVERSION
sort
self.sort(block)
Returns an Array of the set's elements, sorted (in natural order, or by block if given).
var s = Set(3, 1, 4, 1, 5)
say(s.sort) #=> [1, 3, 4, 5]
say(s.sort {|a, b| b <=> a }) #=> [5, 4, 3, 1]
sort_by
self.sort_by(block)
Returns an Array of the set's elements, sorted by the value block returns for each one.
var s = Set(-5, 3, -10, 7)
say(s.sort_by {|n| n.abs }) #=> [3, -5, 7, -10]
to_a
self.to_a
Returns an Array containing every element of the set (in the underlying hash's own unordered order).
var s = Set(1, 2, 3)
say(s.to_a) #=> [1, 2, 3] (order may vary)
Aliases: values, to_array
to_list
self...
Returns every element of the set as a plain list (not wrapped in an Array object, unlike "to_a").
var s = Set(1, 2, 3)
var list = s...
say([list]) #=> [1, 2, 3] (order may vary)
Aliases: operator ...
to_bag
self.to_bag
Converts the set to a Bag (multiset), where every element starts with a count of 1.
var s = Set(1, 2, 3)
var b = s.to_bag
say(b) #=> Bag(1, 2, 3)
to_set
self.to_set
Returns self unchanged (a Set is already a set). Used internally by the set-algebra methods above to coerce any other object into a set before combining it.
var s1 = Set(1, 2, 3)
var s2 = s1.to_set
say(s2) #=> Set(1, 2, 3)
join
self.join(sep)
Joins the elements of the set into a String, separated by sep.
var s = Set(1, 2, 3)
say(s.join(', ')) #=> "1, 2, 3" (order may vary)
INSPECTION
dump
self.dump
Returns a String representation of the set, in the format Set(element, element, ...). Each element is rendered by calling its own dump method if it has one (falling back to plain stringification, or nil, otherwise), and a circular reference back to the set itself is shown as an abbreviated placeholder rather than expanded infinitely. This is also what powers the set's automatic string conversion (e.g. when interpolated into a string).
var s = Set(1, 2, 3)
say(s.dump) #=> "Set(1, 2, 3)"
get_value
self.get_value
Returns the set's contents as a plain Perl array reference, with every nested Sidef object recursively unwrapped to its own raw underlying value via its own get_value. Circular references are handled by reusing the same array reference for a set already seen during the recursion. This is a low-level method, mainly useful for interop rather than everyday Sidef code.
SEE ALSO
Sidef::Types::Hash::Hash, Sidef::Types::Array::Array, Sidef::Types::Set::Bag