Object Maps
Object maps are hash dictionaries. Properties are all dynamic values and can be freely added and retrieved.
type_of()
an object map returns "map"
.
Literal Syntax
Object map literals are built within braces #{
… }
with name:
value pairs separated by
commas ,
:
#{
property:
value,
…,
property:
value}
#{
property:
value,
…,
property:
value,
}
// trailing comma is OK
The property name can be a simple identifier following the same naming rules as variables, or a string literal without interpolation.
Property Access Syntax
Dot notation
The dot notation allows only property names that follow the same naming rules as variables.
object
.
property
Elvis notation
The Elvis notation is similar to the dot
notation except that it returns ()
if the object itself is ()
.
// returns () if object is ()
object?.
property
// no action if object is ()
object?.
property=
value;
Index notation
The index notation allows setting/getting properties of arbitrary names (even the empty string).
object
[
property]
Non-existing property
Trying to read a non-existing property returns ()
instead of causing an error.
This is similar to JavaScript where accessing a non-existing property returns undefined
.
Use the Elvis operator (?.
) to short-circuit
further processing if the object is ()
.
x.a.b.foo(); // <- error if 'x', 'x.a' or 'x.a.b' is ()
x.a.b = 42; // <- error if 'x' or 'x.a' is ()
x?.a?.b?.foo(); // <- ok! returns () if 'x', 'x.a' or 'x.a.b' is ()
x?.a?.b = 42; // <- ok even if 'x' or 'x.a' is ()
Built-in Functions
The following methods operate on object maps.
Function | Parameter(s) | Description |
---|---|---|
get | property name | gets a copy of the value of a certain property (() if the property does not exist) |
set |
| sets a certain property to a new value (property is added if not already exists) |
len | none | returns the number of properties |
clear | none | empties the object map |
remove | property name | removes a certain property and returns it (() if the property does not exist) |
+= operator, mixin | second object map | mixes in all the properties of the second object map to the first (values of properties with the same names replace the existing values) |
+ operator |
| merges the first object map with the second |
== operator |
| are the two object maps the same (elements compared with the == operator, if defined)? |
!= operator |
| are the two object maps different (elements compared with the == operator, if defined)? |
fill_with | second object map | adds in all properties of the second object map that do not exist in the object map |
contains , in operator | property name | does the object map contain a property of a particular name? |
keys | none | returns an array of all the property names (in random order) |
values | none | returns an array of all the property values (in random order) |
to_json | none | returns a JSON representation of the object map (() is mapped to null , all other data types must be supported by JSON) |
Examples
let y = #{ // object map literal with 3 properties
a: 1,
bar: "hello",
"baz!$@": 123.456, // like JavaScript, you can use any string as property names...
"": false, // even the empty string!
`hello`: 999, // literal strings are also OK
a: 42, // <- syntax error: duplicated property name
`a${2}`: 42, // <- syntax error: property name cannot have string interpolation
};
y.a = 42; // access via dot notation
y.a == 42;
y.baz!$@ = 42; // <- syntax error: only proper variable names allowed in dot notation
y."baz!$@" = 42; // <- syntax error: strings not allowed in dot notation
y["baz!$@"] = 42; // access via index notation is OK
"baz!$@" in y == true; // use 'in' to test if a property exists in the object map
("z" in y) == false;
ts.obj = y; // object maps can be assigned completely (by value copy)
let foo = ts.list.a;
foo == 42;
let foo = #{ a:1, }; // trailing comma is OK
let foo = #{ a:1, b:2, c:3 }["a"];
let foo = #{ a:1, b:2, c:3 }.a;
foo == 1;
fn abc() {
{ a:1, b:2, c:3 } // a function returning an object map
}
let foo = abc().b;
foo == 2;
let foo = y["a"];
foo == 42;
y.contains("a") == true;
y.contains("xyz") == false;
y.xyz == (); // a non-existing property returns '()'
y["xyz"] == ();
y.len == (); // an object map has no property getter function
y.len() == 3; // method calls are OK
y.remove("a") == 1; // remove property
y.len() == 2;
y.contains("a") == false;
for name in y.keys() { // get an array of all the property names via 'keys'
print(name);
}
for val in y.values() { // get an array of all the property values via 'values'
print(val);
}
y.clear(); // empty the object map
y.len() == 0;