Standard Library: Collection functions

assoc


[%assoc: keys; values]

map

Creates a map from a list of keys and a list of values. Each key in keys will be matched with the value at the same index in values.

Parameters

keyslist
The keys to store in the map.

valueslist
The values to associate with the keys.

Errors

Raises a runtime error if the lengths of keys and values do not match.

Example

# Generate a map of the "Big Five" personality traits
# with random rating values that add up to 50
<$personality = 
  [assoc:
    (ope; con; ext; agr; neu);
    [shred: 50; 5; [rand: 1; 10]] # Use random variance to reduce trait deviation
  ]
>

# Print the values
[whitespace-fmt:verbatim]
"Openness to experience:"   <personality/ope>\n
"Conscientiousness:"        <personality/con>\n
"Extraversion:"             <personality/ext>\n
"Agreeableness:"            <personality/agr>\n
"Neuroticism:"              <personality/neu>\n


##
  EXAMPLE OUTPUT:

  Openness to experience:   7
  Conscientiousness:        11
  Extraversion:             5
  Agreeableness:            12
  Neuroticism:              15
##

clear


[%clear: collection]

Removes all elements from a list or map.

Parameters

collectionlist | map
The collection to clear.

Errors

Causes a runtime error if collection is not a list or map.

collect


[%collect: values*]

list

Prints a list containing the arguments.

Parameters

valuesany*
The values to store in the list.

filter


[%filter: list; predicate]

list

Runs a predicate function against all items in a list and returns another list containing only the values that the predicate returned @true on.

Parameters

listlist
The input list.

predicatefunction -> bool
The predicate to run against each element in the input list.

Parameters for predicate

itemany
The current item to be checked.

Examples

Filter a list of numbers by only those divisible by 3

<$numbers = (1; 2; 3; 4; 5; 6; 7; 8; 9; 10; 11; 12)>
<$multiples-of-three = [filter: <numbers>; [?:x] { [is-factor: <x>; 3] }]>
[join: <multiples-of-three>; ,\s]
# -> 3, 6, 9, 12

Filter a list of numbers by only odd numbers

<$numbers = (1; 2; 3; 4; 5; 6; 7; 8; 9; 10; 11; 12)>
# `is-odd` is a function, so we can simply pass it in as the predicate!
<$odd-numbers = [filter: <numbers>; <is-odd>]>
[join: <odd-numbers>; ,\s]
# -> 1, 3, 5, 7, 9, 11

Filter a list of words to only those that are 3 letters or less

<$words = [split: "the quick brown fox jumps over the lazy dog";\s]>
<$short-words = [filter: <words>; [?:word] { [le: [len: <word>]; 3] }]>
[join: <short-words>; ,\s]
# -> the fox the dog

index-of


[%index-of: list; value]

int | empty

Returns the index of the first occurrence of value in list. If no match is found, returns ~.

Parameters

listlist
The list to search.

valueany
The value to search for.

Examples

<$letters = (A; A; B; C; C; D; E)>
[index-of: <letters>; A |> assert-eq: 0]
[index-of: <letters>; C |> assert-eq: 3]
[index-of: <letters>; E |> assert-eq: 6]
[index-of: <letters>; F |> assert-eq: ~]

join


[%join: list; separator?]

any*

Prints the elements of a list in order separated by the separator value.

Parameters

listlist
The list whose elements to print.

separatorany (optional)
The separator to print between each element.

last-index-of


[%last-index-of: list; value]

any

Returns the index of the last occurrence of value in list. If no match is found, returns ~.

Parameters

listlist
The list to search.

valueany
The value to search for.

Example

<$letters = (A; A; B; C; C; D; E)>
[last-index-of: <letters>; A |> assert-eq: 1]
[last-index-of: <letters>; C |> assert-eq: 4]
[last-index-of: <letters>; E |> assert-eq: 6]
[last-index-of: <letters>; F |> assert-eq: ~]

map


[%map: list; map-func]

list

Calls the supplied function on each item in a list and returns another list with the results in the same order.

Parameters

listlist
The list whose values to map.

map-funcfunction -> any
The function to map the values with.

Parameters for map-func

itemany
The current item to map.

Example

# Multiple each element of a list by 10
<$numbers = (1; 2; 3; 4; 5; 6; 7; 8; 9; 10)>
<$tens = [map: <numbers>; [?:x] { [mul: <x>; 10] }]>
[join: ,\s; <tens>]
# -> 10, 20, 30, 40, 50, 60, 70, 80, 90, 100

oxford-join


[%oxford-join: comma; conj; comma-conj; list]

any*

A variant of the join function for conveniently formatting comma-separated lists.

Parameters

commaany
The comma value. Separates all items except for the last 2. Unused in lists of 2 items or less.

conjany
The conjunction value. Only used to separate items in lists of exactly 2 values.

comma-conjany
The comma-conjunction value. Separates the final 2 values in lists with more than 2 values.

Remarks

These arguments can be used to configure several aspects of list formatting-- namely, the inclusion of the Oxford comma or the choice of conjunction separating the final two items.

The separator values are applied as follows:

  • Lists of 1 item use no separators.
  • Lists of 2 items use conj to separate the two items.
  • Lists of 3 or more items separate the final two items with comma-conj; all others use comma.

Examples

<$numbers = ()>
[rep: 5][sep: \n]
{
  [push: <numbers>; [step]]
  [oxford-join: ,\s; \sand\s; ,\sand\s; <numbers>]
}

##
  OUTPUT:

  1
  1 and 2
  1, 2, and 3
  1, 2, 3, and 4
  1, 2, 3, 4, and 5
##
<$numbers = ()>
[rep: 5][sep: \n]
{
  [push: <numbers>; [step]]
  [oxford-join: ,\s; \sand\s; \sand\s; <numbers>]
}

##
  OUTPUT:

  1
  1 and 2
  1, 2 and 3
  1, 2, 3 and 4
  1, 2, 3, 4 and 5
##

push


[%push: list; value]

Appends a value to the end of a list.

Parameters

listlist
The list to modify.

valueany
The value to add to the end of list.

pop


[%pop: list]

any

Removes the last value from a list and prints it.

Parameters

listlist
The list to modify.

insert


[%insert: collection; value; pos]

Inserts value into a list or map at the position pos.

If collection is a list, pos must be an int.
If collection is a map, pos may be any non-empty value.

Parameters

collectionlist | map
The collection to modify.

valueany
The value to add to collection.

possome
The location at which to insert the value.
For lists, this is the index; for maps, this is the key.

Errors

Raises an error if pos is out of range or not the correct type for the provided collection.

len


[%len: value]

int

Prints the length of value.

For string, this is the number of graphemes; for list, map, and range, the number of elements. All other value types give a length of 1.

Parameters

valueany
The value whose length to retrieve.

remove


[%remove: collection; pos]

Removes the value at the pos from a list or map.

If collection is a list, pos must be an int.
If collection is a map, pos may be any non-empty value.

Parameters

collectionlist | map
The collection to modify.

possome
The location of the value to remove. Must be of type int for lists.

Errors

Raises an error if pos is an unsupported type for the provided collection.

rev


[%rev: collection]

list | string | block | range

Prints a reversed copy of the input collection.

Parameters

collectionlist | string | block | range
The collection to reverse.

Example

[rev: (foo; bar)]
# -> (bar; foo)

shuffle


[%shuffle: list]

Shuffles the elements of a list in-place.

Parameters

listlist
The input list.

Cost

Where \(n\) = the length of list:

Time complexity
\(O(n)\)

RNG complexity
\(n - 1\)

Example

# Shuffles a list of letters and concatenates them into a single string
<$letters = (A;B;C;D;E;F;G;H;I;J;K;L)>
[shuffle: <letters>]
[join: <letters>]

# ~> GKIBCHLEJADF

shuffled


[%shuffled: list]

list

Creates a shuffled copy of a list.

Parameters

listlist
The input list.

Example

# Shuffle the words in a string
<$message = "the quick brown fox jumps over he lazy dog">
[join: \s; [shuffled: [split: <message>; \s]]]

# ~> jumps fox quick dog lazy the brown the over

sift


[%sift: list; target-size]

Removes random elements from a list in-place until the number of elements in the list reaches target-size. If the number of elements in the list is less than or equal to target-size, this function does nothing.

Parameters

listlist
The input list.

target-sizeint
The maximum number of elements to reduce the list to.

Example

# Remove a random element from a list and print the contents at each iteration
<$list = [split: "Sphinx of black quartz, judge my vow."; \s]>
[rep: [len: <list>]]
[sep: \n]
{
  # Print the current list contents
  [join: \s; <list>]
  # Sift the list to n - 1
  [sift: <list>; [sub: [len: <list>]; 1]]
}

##
  EXAMPLE OUTPUT:

  Sphinx of black quartz, judge my vow.
  Sphinx of black quartz, my vow.
  Sphinx of black quartz, vow.
  Sphinx of black vow.
  Sphinx black vow.
  Sphinx vow.
  vow.
##

sifted


[%sifted: list; target-size]

list

Returns a copy of a list with random elements removed until the number of elements in the list copy reaches target-size. If the number of elements in the list is less than or equal to target-size, this function simply returns an exact copy of the original list.

Parameters

listlist
The input list.

target-sizeint
The maximum number of elements to reduce the list to.

Example

# Create a random subset of abilities for a character

<$char-traits = (
  berserk;    xray-vision;  speaks-to-bees; 
  vampirism;  flying;       telekinesis; 
  many-legs;  high-jump;    bee-allergy
)>

<$npc = @(
  name = "Foo Bar";
  traits = [sifted: <char-traits>; 2];
)>

# Print character info
<npc/name>: '[join: ,\s; <npc/traits>]

# ~> Foo Bar: speaks-to-bees, many-legs

squish


[%squish: list; target-size]

Merges random adjacent elements in a list using addition until the number of elements in the list reaches target-size. If the number of elements in the list is less than or equal to target-size, this function does nothing.

Parameters

listlist
The input list.

target-sizeint
The maximum number of elements to reduce the list to.

Example

# Merge random items in a number list
<$numbers = (100; 100; 100; 100; 100; 100; 100; 100; 100; 100)>

# Print the original list
Before: '[join: ,\s; <numbers>]\n

# Squish the list down to 5 elements
[squish: <numbers>; 5]

# Print the modified list
After: '[join: ,\s; <numbers>]\n

##
  EXAMPLE OUTPUT:

  Before: 100, 100, 100, 100, 100, 100, 100, 100, 100, 100
  After: 100, 200, 100, 400, 200
##

squished


[%squished: list; target-size]

list

Returns a copy of a list with random adjacent elements merged using addition until the number of elements in the list copy reaches target-size. If the number of elements in the list is less than or equal to target-size, this function simply returns an exact copy of the original list.

Parameters

listlist
The input list.

target-sizeint
The maximum number of elements to reduce the list copy to.

sort


[%sort: list]

Sorts the elements of a list in-place in ascending order.

Parameters

listlist
The input list.

sorted


[%sorted: list]

list

Creates a copy of a list with its elements sorted in ascending order.

Parameters

listlist
The input list.

sum


[%sum: list]

any

Adds the elements of a list together from left to right and prints the result.

take


[%take: collection; pos]

any

Removes the value at pos from a list or map and prints it.

Parameters

collectionlist | map
The input collection.

possome
The location of the value to take. If collection is a list, this argument must be an int.

Errors

Raises an error if pos is not a valid location in the collection.

translate


[%translate: list; map]

list

Matches each item in a list to a map and returns a list with the corresponding map values. Values that have no corresponding key in the map are passed through as-is.

Parameters

listlist
The input list.

mapmap
A map associating items in list with their replacements.

Example

# Constructs a substitution cipher function
[$make-cipher: alphabet] {
  <
    $letters = [split: <alphabet>];
    $sub-letters = [shuffled: <letters>];
    $cipher = [assoc: <letters>; <sub-letters>];
    $cipher-rev = [assoc: <sub-letters>; <letters>];
  >
  # Return cipher functions
  @(
    encode = [?: message] {
      [sum: [translate: [split: <message>]; <cipher>]]
    };
    decode = [?: message] {
      [sum: [translate: [split: <message>]; <cipher-rev>]]
    };
  )
}

# Create a cipher and encode/decode a message
<$cipher = [make-cipher: "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz"]>
<$secret-message = "The quick brown fox jumps over the lazy dog.">
<$encoded-message = [cipher/encode: <secret-message>]>
<$decoded-message = [cipher/decode: <encoded-message>]>

# Finally, print the result
Original: \"<secret-message>\"\n
Encoded: \"<encoded-message>\"\n
Decoded: \"<decoded-message>\"\n

##
  EXAMPLE OUTPUT:

  Original: "The quick brown fox jumps over the lazy dog."
  Encoded: "kWj KGvaF QcDiq HDx CGpMJ DOjc AWj Tsyt fDN."
  Decoded: "The quick brown fox jumps over the lazy dog."
##

zip


[%zip: list-a; list-b; zip-func]

list

Returns a new list that combines each pair of items from the two input lists using the specified function. The lists do not need to be the same length; if there is a difference, it will be made up with empties.

Parameters

list-alist
A list containing the left-hand values of the zip.

list-blist
A list containing the right-hand values of the zip.

zip-funcfunction -> any
A function that prints a new value for each corresponding pair of values from list-a and list-b.

Parameters for zip-func

aany
The current value from list-a.

bany
The current value from list-b.

Examples

# Dot product
[$dot: a; b] {
  [zip: <a>; <b>; <mul> |> sum]
}

[dot: (1; 2; 3); (4; 5; 6)] # 32