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.
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:
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]}