An entity is a collection of property-value or key-value pairs. Entities are used to store/represent data in Sequence.
Entities are defined in SCL using round brackets:
Entities can have any number of properties
(Property: 'Value' Key: 'AnotherValue' NumberProperty: 123)
You can quote property names to include spaces and other characters:
('My Property': 123)
Entity values can have any type, including arrays and entities.
To get a property value from an entity use the
- <entity> = (Foo: 'a' Bar: 'b')
- EntityGetValue <entity> 'Foo'
# returns: 'a'
A shorthand for
EntityGetValue is a period / full stop:
- <entity> = (Foo: 'a' Bar: 'b')
- <entity>.Foo # returns: 'a'
- 5 * (Number: 5).Number # returns: 25
To retrieve nested entities, use multiple periods:
- <entity> = (Foo: (Bar: 'a'))
- <entity>.Foo.Bar # returns: 'a'
For properties with spaces or other unusual characters use
- <entity> = ('multi word property name': 'a')
- EntityGetValue <entity> 'multi word property name' # returns: 'a'
It's also possible to get property values using the square bracket notation:
- <entity> = ('foo': 'a')
- <entity>['foo'] # returns: 'a'
This is a legacy feature and may be deprecated at some time in the future.
You can use periods in property names to nest properties:
# The following are all equivalent
- <entity1> = (a: (b: (c: 123)))
- <entity2> = (a.b.c: 123)
- <entity3> = ('a'.'b'.'c': 123)
- <entity4> = (a.'b'.c: 123)
You can also retrieve nested property values using the same notation:
- <entity> = (a: (b: (c: 123)))
- EntityGetValue <entity> 'a.b.c' # returns: 123
You can combine entities with the
Nested entities will be combined. For all other properties, the value of the entity on the right will be used.
- (Foo: 'a') + (Bar: 'b') # (Foo: 'a' Bar: 'b')
- (Foo: 'a' Bar: 'b') + (Bar: 'c') # (Foo: 'a' Bar: 'c')
- (x: (Foo: 'a')) + (x: (Bar: 'b')) # (x:(Foo: 'a' Bar: 'b'))
- (x: (Foo: 'a' Bar: 'b')) + (x: (Bar: 'c')) # (x:(Foo: 'a' Bar: 'c'))
A primary use case of SCL is handling sequential collections (lists or streams) of entities.
It is easy to read and write different formats like CSV, Concordance, and JSON.
There are also steps for filtering, mapping, sorting, and distincting entities.
See steps prefixed with
Entity for more details.
| FromCSV # Convert CSV into a stream of entities
| Filter (<>.artist == 'Blake, Robert') # Filter the stream
# Change the artist's name to uppercase:
| EntityMap (in <> set: 'artist' to: (StringToCase (from <> 'artist') TextCase.Upper))
# Rename properties from 'artist' to 'Artist Name' and 'artistId' to 'Artist Id':
| EntityMapProperties (artist: 'Artist Name' artistId: 'Artist Id')
| Sort (<>.year) # sort by year
| Distinct (<>.id) # remove duplicate entries using the 'id' as the key
| ToJsonArray # convert the entity stream to JSON
| FileWrite 'artwork_data.json'
Some steps require a function argument which will be called on every element of the array.
For example the
Filter function filters an array to only elements which meet a
particular condition and that condition must be provided as an argument.
The function you provide can access the member of the array which is being evaluated in three ways, all of which are equivalent:
- <elements> = FileRead 'artwork_data.csv'| FromCSV # Convert CSV into a stream of entities
- <elements> | Filter (<item>.artist == 'Blake, Robert') | Log # Use the variable named <item>>
- <elements> | Filter (<myvariable> => <myvariable>.artist == 'Blake, Robert') | Log # Use a different variable name
- <elements> | Filter (<>.artist == 'Blake, Robert') | Log # Use the automatic variable <>