class SetHash

Mutable collection of distinct objects
class SetHash does Setty { }

A SetHash is a mutable set, meaning a collection of distinct elements in no particular order. (For immutable sets, see Set instead.)

Objects/values of any type are allowed as set elements. Within a Set, every element is guaranteed to be unique (in the sense that no two elements would compare positively with the === operator):

my $fruits = <peach apple orange apple apple>.SetHash;

say $fruits.elems;      # OUTPUT: «3␤»
say $fruits.keys.sort;  # OUTPUT: «apple orange peach␤»

Just like Sets, SetHashes can be treated as object hashes using the { } postcircumfix operator, which returns the value True for keys that are elements of the set, and False for keys that aren't.

my $fruits = <peach apple orange apple apple>.SetHash;

say $fruits<apple>;     # OUTPUT: «True␤»
say $fruits<kiwi>;      # OUTPUT: «False␤»

Unlike Sets, SetHashes are mutable. You can add an item or list of items to the SetHash with the set method and can remove an item or list of items with the unset method:

my $fruits = <peach>.SetHash;
$fruits.set('apple');
say $fruits;            # OUTPUT: «SetHash(apple peach)␤»

$fruits.unset('peach');
say $fruits;            # OUTPUT: «SetHash(apple)␤»

$fruits.set(<kiwi banana apple>);
say $fruits;            # OUTPUT: «SetHash(apple banana kiwi)␤»

$fruits.unset(<apple banana kiwi>);
say $fruits;            # OUTPUT: «SetHash()␤»

Be careful not to confuse the set method, which adds an item to a SetHash with the Set method, which converts the mutable SetHash into an immutable Set.

As an alternative to using the set and unset methods, you can also add or remove set elements by assigning a value that boolifies to True or False, respectively:

my $fruits = <peach apple orange>.SetHash;

$fruits<apple kiwi> = False, True;
say $fruits.keys.sort;  # OUTPUT: «kiwi orange peach␤»

Here is a convenient shorthand idiom for adding and removing SetHash elements using assignment:

my SetHash $fruits .= new;
say $fruits<cherry>;      # OUTPUT: «False␤»
$fruits<cherry>++;
say $fruits<cherry>;      # OUTPUT: «True␤»
$fruits<apple banana kiwi>»++; # Add multiple elements

$fruits<cherry>--;
say $fruits<cherry>;      # OUTPUT: «False␤»
$fruits<banana kiwi>»--; # Remove multiple elements

Creating SetHash objects

SetHashes can be composed using SetHash.new. Any positional parameters, regardless of their type, become elements of the set:

my $n = SetHash.new: "zero" => 0, "one" => 1, "two" => 2;
    say $n.keys.raku;        # OUTPUT: «(:two(2), :zero(0), :one(1)).Seq␤»
    say $n.keys.map(&WHAT);  # OUTPUT: «((Pair) (Pair) (Pair))␤»

Alternatively, the .SetHash coercer (or its functional form, SetHash()) can be called on an existing object to coerce it to a SetHash. Its semantics depend on the type and contents of the object. In general it evaluates the object in list context and creates a set with the resulting items as elements, although for Hash-like objects or Pair items, only the keys become elements of the set - and keys mapped to values which boolify to False are skipped:

my $n = ("zero" => 0, "one" => 1, "two" => 2).SetHash;
    say $n.keys.raku;        # OUTPUT: «("one", "two").Seq␤»
    say $n.keys.map(&WHAT);  # OUTPUT: «((Str) (Str))␤»

It is also possible to initialize a single key with the use of {}:

my $sh = SetHash.new;
    $sh{ 'key1' } = True;
    $sh{ 'key2' } = 'Hello World!';
    $sh{ 'key3' } = 0;  # does not store the key since 0.Bool is False
    say $sh;            # OUTPUT: «SetHash(key1 key2)␤»
    say $sh.keys.raku;  # OUTPUT: «("key1", "key2").Seq␤»

or, in order to initialize more than one key at the same time, use a list assignment:

my $sh = SetHash.new;
   $sh{ 'a', 'b', 'c' } = True, False, True;
   say $sh.keys.raku;  # OUTPUT: «("a", "c").Seq␤»

You can also create SetHash masquerading as a hash by using the is trait:

my %sh is SetHash = <a b c>;
    say %sh<a>;  # OUTPUT: «True␤»
    say %sh<d>;  # OUTPUT: «False␤»

Since 6.d (2019.03 and later) it is also possible to specify the type of values you would like to allow in a SetHash. This can either be done when calling .new:

# only allow Pairs
    my $n = SetHash[Pair].new: "zero" => 0, "one" => 1, "two" => 2;

or using the masquerading syntax:

# only allow strings
    my %sh is SetHash[Str] = <a b c>;
    say %sh<a>;  # OUTPUT: «True␤»
    say %sh<d>;  # OUTPUT: «False␤»
# only allow whole numbers
    my %sh is SetHash[Int] = <a b c>;
    # Type check failed in binding; expected Int but got Str ("a")

Operators

See Operators with set semantics for a complete list of "set operators" applicable to, among other types, SetHash.

Examples:

my ($a, $b) = SetHash.new(1, 2, 3), SetHash.new(2, 4);

say $a (<) $b;  # OUTPUT: «False␤»
say $a (&) $b;  # OUTPUT: «SetHash(2)␤»
say $a (^) $b;  # OUTPUT: «SetHash(1 3 4)␤»
say $a (|) $b;  # OUTPUT: «SetHash(1 2 3 4)␤»

# Unicode versions:
say $a ⊂ $b;  # OUTPUT: «False␤»
say $a ∩ $b;  # OUTPUT: «SetHash(2)␤»
say $a ⊖ $b;  # OUTPUT: «SetHash(1 3 4)␤»
say $a ∪ $b;  # OUTPUT: «SetHash(1 2 3 4)␤»

Methods

method set

method set(SetHash:D: \to-set --> Nil)

When given single key, set adds it to the SetHash. When given a List, Array, Seq, or any other type that does the Iterator Role, set adds each element of the Iterator as a key to the SetHash.

Note: since version 2020.02.

method unset

method unset(SetHash:D: \to-unset --> Nil)

When given single key, unset removes it from the SetHash. When given a List, Array, Seq, or any other type that does the Iterator Role, unset removes each element of the Iterator from the SetHash (if it was present as a key).

Note: since version 2020.02.

See Also

Sets, Bags, and Mixes

See Also

class Array

Sequence of itemized values

class Bag

Immutable collection of distinct objects with integer weights

class BagHash

Mutable collection of distinct objects with integer weights

class Capture

Argument list suitable for passing to a Signature

class Hash

Mapping from strings to itemized values

class IterationBuffer

Low level storage of positional values

class List

Sequence of values

class Map

Immutable mapping from strings to values

class Mix

Immutable collection of distinct objects with Real weights

class MixHash

Mutable collection of distinct objects with Real weights

class NFC

Codepoint string in Normal Form C (composed)

class NFD

Codepoint string in Normal Form D (decomposed)

class NFKC

Codepoint string in Normal Form KC (compatibility composed)

class NFKD

Codepoint string in Normal Form KD (compatibility decomposed)

class Pair

Key/value pair

class PseudoStash

Stash type for pseudo-packages

class Range

Interval of ordered values

class Seq

An iterable, potentially lazy sequence of values

class Set

Immutable collection of distinct objects

class Slip

A kind of List that automatically flattens into an outer container

class Stash

Table for "our"-scoped symbols

class Uni

A string of Unicode codepoints

class utf8

Mutable uint8 buffer for utf8 binary data

The Camelia image is copyright 2009 by Larry Wall. "Raku" is trademark of the Yet Another Society. All rights reserved.