class Set
Error ReportCollection examples

Immutable collection of distinct objects

class Set does Setty { }

A Set is an immutable set, meaning a collection of distinct elements in no particular order. (For mutable sets, see SetHash 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 = set <peach apple orange apple apple>;
say $fruits.elems;      # OUTPUT: «3␤» 
say $fruits.keys.sort;  # OUTPUT: «apple orange peach␤» 

Sets 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 = set <peach apple orange apple apple>;
say $fruits<apple>;  # OUTPUT: «True␤» 
say $fruits<kiwi>;   # OUTPUT: «False␤»

Creating Set objects

Sets can be composed using the set subroutine (or Set.new, for which it is a shorthand). Any positional parameters, regardless of their type, become elements of the set:

my $n = set "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 .Set coercer (or its functional form, Set()) can be called on an existing object to coerce it to a Set. 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).Set;
say $n.keys.raku;        # OUTPUT: «("one", "two").Seq␤» 
say $n.keys.map(&WHAT);  # OUTPUT: «((Str) (Str))␤»

Furthermore, you can get a Set by using set operators (see next section) on objects of other types such as List, which will act like they internally call .Set on them before performing the operation. Be aware of the tight precedence of those operators though, which may require you to use parentheses around arguments:

say (1..5(^) 4;  # OUTPUT: «Set(1 2 3 5)␤»

Of course, you can also create a Set with the .new method.

my $fruits = Set.new( <peach apple orange apple apple> );

Since 6.d (2019.03 and later) you can also use this syntax for parameterization of the Set, to specify which type of values are acceptable:

# only allow strings (Str) in the Set 
my $fruits = Set[Str].new( <peach apple orange apple apple> );
# only allow whole numbers (Int) in the Set 
my $fruits = Set[Int].new( <peach apple orange apple apple> );
# Type check failed in binding; expected Int but got Str ("peach")

Finally, you can create Set masquerading as a hash by using the is trait:

my %s is Set = <a b c>;
say %s<a>;  # True 
say %s<d>;  # False

Since 6.d (2019.03 and later), this syntax also allows you to specify the type of values you would like to allow:

# limit to strings 
my %s is Set[Str= <a b c>;
say %s<a>;  # True 
say %s<d>;  # False 
# limit to whole numbers 
my %s is Set[Int= <a b c>;
# Type check failed in binding; expected Int but got Str ("a")


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


my ($a$b= set(123), set(24);
say $a (<) $b;  # OUTPUT: «False␤» 
say $a (&) $b;  # OUTPUT: «Set(2)␤» 
say $a (^) $b;  # OUTPUT: «Set(1 3 4)␤» 
# Unicode versions: 
say $a  $b;  # OUTPUT: «False␤» 
say $a  $b;  # OUTPUT: «Set(2)␤» 
say $a  $b;  # OUTPUT: «Set(1 3 4)␤» 


sub set

sub set(*@args --> Set)

Creates a Set from the given @args

See Also

Sets, Bags, and Mixes