Skip to content

Vectors๐Ÿ”—

Preview Restrictions

HDevelopEVO does not support vectors yet.

A vector is a container that can hold an arbitrary number of elements, all of which must have the exact same variable type (tuple, iconic object, or vector). The variable type โ€œvectorโ€ is specific to HDevelop/HDevelopEVO.

A vector of tuples or objects is called one-dimensional, a vector of vectors of tuples or objects is two-dimensional, and so on. The type of a vector must not change within the program. Its dimension has to remain constant, and vectors of tuples must not be assigned iconic objects or vice versa.

This is the definition of a vector in EBNF (Extended Backus-Naur Form) grammar:

vector     = "" ;
list     = tuplelist | objectlist | vectorlist ;
tuplelist  = tuple,  ;
objectlist = object,  ;
vectorlist = vector,  ;
tuple    = "[" control "]" ;
control    = string | integer | real | boolean ;

Construction of Vectors๐Ÿ”—

A vector is defined by providing a comma-separated list of its elements in curly brackets.

One-dimensional vector
vectorT :=  {[1], [2], [3]}

This is equivalent to

vectorT :=  {1, 2, 3}   // tuples of length 1 do not require square brackets

Variable names or arbitrary expressions can be used instead of constants:

t1 := 1
vectorT := {t1, t1 * 2, 3}

The following example defines a vector of iconic objects:

read_image (Image, 'clip')
threshold (Image, Region, 0, 63)
connection (Region, ConnectedRegions)
vectorO := {Image, Region, ConnectedRegions}

The following example defines a two-dimensional vector variable:

Two-dimensional vector
vectorV := {vectorT, {[4,5,6,7], [8,9]}}

It is also possible to define vector variables using the .at() and .insert() operations.

The list of the vectorโ€™s elements may also be empty, that is, an empty vector {} is valid as in the following example:

vectorV2 := {{1,2}, {}}

Note, however, that an empty vector has no specific type. Therefore, all of the following three empty assignments are valid:

vectorO2 := vectorO
vectorT2 := vectorT
vectorV2 := vectorV

vectorO2 := {}
vectorT2 := {}
vectorV2 := {}

Assigning an empty vector to a vector variable is equivalent to the .clear() operation. This means that the assignment of an empty vector to a variable is not sufficient to define the variableโ€™s type; see the section about variable types. Such a variable will have an undefined type (and, therefore, be invalid) unless its type is defined properly elsewhere in the program.

Accessing and Setting Vector Elements๐Ÿ”—

A single vector element is accessed using the .at() operation, the argument of which ranges from 0 to the number of vector elements minus 1. Several .at() operations can be combined to access the subelements of multi-dimensional vectors.
Trying to access non-existing vector elements throws a runtime error.

tuple  := vectorT.at(0)         // tuple  := 1
region := vectorO.at(1)         // region := Region
vector := vectorV.at(0)         // vector := 
tuple  := vectorV.at(1).at(1)   // tuple  := [8, 9]

The .at() operation is also used to set vector elements. Writing to a non-existing vector element is allowed. If necessary, the vector is automatically filled with empty elements.

vectorT.at(2) := 33        // vectorT := {[1], [2], [33]}
vectorE.at(4) := 'text'    // vectorE := {[], [], [], [], 'text'}

The at() operation also allows you to construct a vector dynamically in a loop:

for i:= 0 to 5 by 1
  vecT.at(i) := gen_tuple_const(i,5)
endfor

The .insert() operation specifies an index position and a value. It shifts the values from the given index to the end by one position, and sets the value at the index to the new value.

The .remove() operation performs the opposite operation. It removes the value at the specified position and moves all following values to the left.

vectorT.insert(1, 99)        // vectorT := {[1], [99], [2], [33]}
vectorT.remove(2)            // vectorT := {[1], [99], [33]}

Like with the .at() operation, the vector is automatically filled with empty elements if necessary.

vectorNew.insert(2, 3)       // vectorNew := {[], [], [3]}

The .concat() operation concatenates two vectors of the same type and dimension.

vectorC := vectorT.concat(vectorNew)   // vectorC := {[1], [99], [33], [], [], [3]}

Getting the Number of Vector Elements๐Ÿ”—

The number of vector elements is queried using the length() operation.

i := vectorT.length()         // i := 3
j := vectorV.length()         // j := 2
k := vectorV.at(0).length()   // k := 3

Clearing a Vector Variable๐Ÿ”—

The .clear() operation removes all elements from the corresponding vector variable. Note however that the cleared vector still keeps its variable type.

vectorT.clear()
* vectorT := vectorO         // illegal: vectorT is a tuple vector
* vectorT := vectorV         // illegal: vectorT is one-dimensional

Modifying Vector Operations๐Ÿ”—

The vector operations .clear(), .insert(), and .remove() are special in that they modify the input vector. Therefore, they may only be used within an independent program statement, expression, and not within expressions for assignments or input parameters. However, it is allowed to chain more than one modifying vector operation in an executable expression:

v := {1, 2, 3}
v.insert(1, 5).insert(2, 4).remove(0)        // sets v to {5, 4, 2, 3}

Testing Vector Variables for (In)Equality๐Ÿ”—

The operations == and != are used to test two vector variables for equality or inequality, respectively.

Converting Vectors to Tuples and Vice-Versa๐Ÿ”—

A vector variable can be flattened to a tuple using the convenience operator convert_vector_to_tuple. It concatenates all tuple values that are stored in the input vector and stores them in the output tuple.

convert_vector_to_tuple (vectorV, T)    // T := [1, 2, 3, 4, 5, 6, 7, 8, 9]

The convenience operator convert_tuple_to_vector_1d stores the elements of the input tuple as single elements of the one-dimensional output vector.

convert_tuple_to_vector_1d (T, 1, V)   // V := {[1],[2],[3],[4],[5],[6],[7],[8],[9]}