<commit_before>=begin pod

=TITLE class Hash

=SUBTITLE Mapping from strings to itemized values

    class Hash is EnumMap { }

A Hash is a mutable mapping from keys to values (called I<dictionary>,
I<hash table> or I<map> in other programming languages). The values are
all scalar containers, which means you can assign to them.

Hashes are usually stored in variables with the percent C<%> sigil.

Hash elements are accessed by key via the C<{ }> postcircumfix operator:

    my $home = %*ENV{'HOME'};

For literal string keys without whitespace, C< < > > can be used instead:

    my $home = %*ENV<HOME>;

You can add new pairs simply by assigning to an unused key:

    my %h;
    %h{'new key'} = 'new value';

=head1 Hash assignment

Assigning a list of elements to a hash variable first empties the variable,
and then iterates the elements of the right-hand side. If an element is an
L<Enum> (or a subclass like L<Pair>), its key is taken as a new hash key,
and its value as the new hash value for that key. Otherwise the value
is coerced to L<Str> and used as a hash key, while the next element of the
list is taken as the corresponding value.

    my %h = 'a', 'b', c => 'd', 'e', 'f';
    # same as
    my %h = a => 'b', c => 'd', e => 'f';
    # or
    my %h = <a b c d e f>;

If an L<Enum> is encountered where a value is expected, it is used as a
hash value:

    my %h = 'a', 'b' => 'c';
    say %h<a>.WHAT;             # Pair();
    say %h<a>.key;              # b

If the same key appears more than once, the value associated with its last
occurrence is stored in the hash:

    my %h = a => 1, a => 2;
    say %h<a>;                  # 2

=head1 Looping over hash keys and values

A common idiom for processing the elements in a hash is to loop over the
keys and values, for instance,

    my %vowels = 'a' => 1, 'e' => 2, 'i' => 3, 'o' => 4, 'u' => 5;
    for %vowels.kv -> $vowel, $index {
	    "$vowel: $index".say;
    }

gives output similar to this:

    a: 1
    e: 2
    o: 4
    u: 5
    i: 3

where we have used the C<kv> method to extract the keys and their respective
values from the hash, so that we can pass these values into the loop.

Note that the order of the keys and values printed cannot be relied upon;
the elements of a hash are not always stored the same way in memory for
different runs of the same program.  Sometimes one wishes to process the
elements sorted on, e.g. the keys of the hash.  If one wishes to print the
list of vowels in alphabetical order then one would write

    my %vowels = 'a' => 1, 'e' => 2, 'i' => 3, 'o' => 4, 'u' => 5;
    for %vowels.sort(*.key)>>.kv -> ($vowel, $index) {
	    "$vowel: $index".say;
    }

which prints

    a: 1
    e: 2
    i: 3
    o: 4
    u: 5

and is in alphabetical order as desired.  To achieve this result, we sorted
the hash of vowels by key (C<%vowels.sort(*.key)>) which we then ask for its
keys and values by applying the C<.kv> method to each element via the unary
C< >> > hyperoperator.  The output of this operation is a C<Parcel>, the
items of which need to be passed into the C<for> loop's block as arguments,
hence the need to wrap the key/value pairs in parentheses.  Wrapping the
C<for> loop's input in parentheses is not normally necessary when the input
is a C<List>.

=head1 Methods

=head2 method push

    multi method push(Hash:D: *@new)<commit_msg>Added usage statements to C<push><commit_after>=begin pod

=TITLE class Hash

=SUBTITLE Mapping from strings to itemized values

    class Hash is EnumMap { }

A Hash is a mutable mapping from keys to values (called I<dictionary>,
I<hash table> or I<map> in other programming languages). The values are
all scalar containers, which means you can assign to them.

Hashes are usually stored in variables with the percent C<%> sigil.

Hash elements are accessed by key via the C<{ }> postcircumfix operator:

    my $home = %*ENV{'HOME'};

For literal string keys without whitespace, C< < > > can be used instead:

    my $home = %*ENV<HOME>;

You can add new pairs simply by assigning to an unused key:

    my %h;
    %h{'new key'} = 'new value';

=head1 Hash assignment

Assigning a list of elements to a hash variable first empties the variable,
and then iterates the elements of the right-hand side. If an element is an
L<Enum> (or a subclass like L<Pair>), its key is taken as a new hash key,
and its value as the new hash value for that key. Otherwise the value
is coerced to L<Str> and used as a hash key, while the next element of the
list is taken as the corresponding value.

    my %h = 'a', 'b', c => 'd', 'e', 'f';
    # same as
    my %h = a => 'b', c => 'd', e => 'f';
    # or
    my %h = <a b c d e f>;

If an L<Enum> is encountered where a value is expected, it is used as a
hash value:

    my %h = 'a', 'b' => 'c';
    say %h<a>.WHAT;             # Pair();
    say %h<a>.key;              # b

If the same key appears more than once, the value associated with its last
occurrence is stored in the hash:

    my %h = a => 1, a => 2;
    say %h<a>;                  # 2

=head1 Looping over hash keys and values

A common idiom for processing the elements in a hash is to loop over the
keys and values, for instance,

    my %vowels = 'a' => 1, 'e' => 2, 'i' => 3, 'o' => 4, 'u' => 5;
    for %vowels.kv -> $vowel, $index {
	    "$vowel: $index".say;
    }

gives output similar to this:

    a: 1
    e: 2
    o: 4
    u: 5
    i: 3

where we have used the C<kv> method to extract the keys and their respective
values from the hash, so that we can pass these values into the loop.

Note that the order of the keys and values printed cannot be relied upon;
the elements of a hash are not always stored the same way in memory for
different runs of the same program.  Sometimes one wishes to process the
elements sorted on, e.g. the keys of the hash.  If one wishes to print the
list of vowels in alphabetical order then one would write

    my %vowels = 'a' => 1, 'e' => 2, 'i' => 3, 'o' => 4, 'u' => 5;
    for %vowels.sort(*.key)>>.kv -> ($vowel, $index) {
	    "$vowel: $index".say;
    }

which prints

    a: 1
    e: 2
    i: 3
    o: 4
    u: 5

and is in alphabetical order as desired.  To achieve this result, we sorted
the hash of vowels by key (C<%vowels.sort(*.key)>) which we then ask for its
keys and values by applying the C<.kv> method to each element via the unary
C< >> > hyperoperator.  The output of this operation is a C<Parcel>, the
items of which need to be passed into the C<for> loop's block as arguments,
hence the need to wrap the key/value pairs in parentheses.  Wrapping the
C<for> loop's input in parentheses is not normally necessary when the input
is a C<List>.

=head1 Methods

=head2 method push

Defined as:

    multi method push(Hash:D: *@new)

Usage:

    push HASH, VALUES
    HASH.push(VALUES)
    HASH.push: (VALUES)
{'fraction_non_alphanumeric': 0.09862452443664033, 'fraction_numerical': 0.007901668129938543, 'mean_word_length': 2.953152111046848, 'pattern_counts': {'":': 0, '<': 52, '<?xml version=': 0, '>': 98, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '5240819', 'n_tokens_mistral': 2289, 'n_tokens_neox': 2165, 'n_words': 1128}