Operations#

AssociativeArray() -> Assoc#
Default: Any                    Default: 

Create the null associative array \(A\) with no index universe. The first assignment to \(A\) will determine its index universe. The optional parameter Default := D allows one to associate the default value \(D\) to \(A\) (so \(A[x]\) will return \(D\) if \(x\) is not in the keys of \(A\)).

AssociativeArray(I): Str -> Assoc#
Default: Any                    Default: 

Create the empty associative array \(A\) with index universe \(I\). The optional parameter Default := D allows one to associate the default value \(D\) to \(A\) (so \(A[x]\) will return \(D\) if \(x\) is not in the keys of \(A\)).

A[x] := y: Assoc, Elt, Elt#

Set the value in \(A\) associated with index \(x\) to be \(y\). If \(x\) is not coercible into the current index universe \(I\) of \(A\), then an attempt is first made to lift the index universe of \(A\) to contain both \(I\) and \(x\).

In a nested assignment such as A[x][z] := y, if \(x\) is not in the keys of \(A\) but a default value \(D\) was specified when \(A\) was created, then \(A[x]\) is first set to \(D\) and the assignment then proceeds on that value. Thus arrays of arrays may be built up without initializing each level explicitly (see the example below).

A[x]: Assoc, Elt -> Elt#

Given an index \(x\) coercible into the index universe \(I\) of \(A\), return the value associated with \(x\). If \(x\) is not in the keys of \(A\), then: (1) if a default value \(D\) was specified when \(A\) was created, then \(D\) is returned; (2) otherwise, an error is raised.

IsDefined(A, x): Assoc, Elt -> Bool, Elt#

Given an index \(x\) coercible into the index universe \(I\) of \(A\), return whether \(A[x]\) is currently defined, and if so, return also the value \(A[x]\). This is the case if \(x\) is in the keys of \(A\) or \(A\) has a default value.

IsInKeys(A, x): Assoc, Elt -> Bool, Elt#

Given an index \(x\) coercible into the index universe \(I\) of \(A\), return whether \(x\) is explicitly in the keys of \(A\) and if so, return also the value \(A[x]\).

Remove(~A, x): Assoc, Elt#

(Procedure.) Destructively remove the value indexed by \(x\) from the array \(A\). If \(x\) is not present as an index, then nothing happens (i.e., an error is not raised).

Universe(A): Assoc -> Str#

Given an associative array \(A\), return the index universe \(I\) of \(A\), in which the keys of \(A\) currently lie.

# A: Assoc -> RngIntElt#

Given an associative array \(A\), return the number of items stored in \(A\).

Keys(A): Assoc -> SetEnum#

Given an associative array \(A\), return the current keys of \(A\) as a set. Warning: this constructs a new copy of the set of keys, so should only be called when that is needed; it is not meant to be used as a quick access function.

Values(A): Assoc -> List#

Given an associative array \(A\), return the current values of \(A\) as an unsorted list (a list is returned since the values need not lie in a fixed universe but may be of any type). Warning: this constructs a new copy of the list of values, so should only be called when that is needed; it is not meant to be used as a quick access function.

Example: Assoc Creation (ex-c3ad44)#

This example shows simple use of associative arrays. First we create an array indexed by rationals.

> A := AssociativeArray();
> A[1/2] := 7;
> A[3/8] := "abc";
> A[3] := 3/8;
> A[1/2];
7
> IsDefined(A, 3);
true 3/8
> IsDefined(A, 4);
false
> IsDefined(A, 3/8);
true abc
> Keys(A);
{ 3/8, 1/2, 3 }
> Values(A);
[* 7, abc, 3/8 *]
> for x in Keys(A) do x, A[x]; end for;
1/2 7
3/8 abc
3 3/8
> Remove(~A, 3/8);
> IsDefined(A, 3/8);
false
> Keys(A);
{ 1/2, 3 }
> Values(A);
[* 7, 3/8 *]
> Universe(A);
Rational Field

Run in calculator

We repeat that an associative array can be indexed by elements of any structure. We now index an array by elements of the symmetric group \(S_3\).

> G := Sym(3);
> A := AssociativeArray(G);
> v := 1; for x in G do A[x] := v; v +:= 1; end for;
> A;
Associative Array with index universe GrpPerm: G, Degree 3, Order 2 * 3
> Keys(A);
{
    (1, 3, 2),
    (2, 3),
    (1, 3),
    (1, 2, 3),
    (1, 2),
    Id(G)
}
> A[G!(1,3,2)];
3

Run in calculator

The following shows how the parameter Default can be used when an associative array \(A\) is created.

> A := AssociativeArray(: Default := []);
> x := 3; y := 5;
> Append(~A[x], y);
> assert A[x] eq [y];
> assert Keys(A) eq {x};
> assert Values(A) eq [* [ y ] *];
> IsDefined(A, x);
true [ 5 ]
> IsInKeys(A, x);
true [ 5 ]
> IsDefined(A, 4);
true []
> IsInKeys(A, 4);
false

Run in calculator

Here we can append an element to \(A[x]\) even when \(x\) is not yet in the keys of \(A\); in such a case, \(A[x]\) is initially taken to be \([]\) and so can be appended to without error.

Since the default may itself be an associative array with a default, nested arrays may be built up in the same way, without initializing any of the intermediate levels.

> A := AssociativeArray(: Default := AssociativeArray(: Default := []));
> Append(~A[1][2], 3);
> Append(~A[1][2], 4);
> Append(~A[5][6], 7);
> A[1][2];
[ 3, 4 ]
> Keys(A);
{ 1, 5 }
> Keys(A[5]);
{ 6 }

Run in calculator

An index is only added to the keys of \(A\) when something is actually assigned to it, so simply reading a value leaves \(A\) unchanged.

> A[9][9];
[]
> Keys(A);
{ 1, 5 }

Run in calculator