Working with vectors
The formula language also supports vectors, which are lists of values of the same type. They are created using square brackets (e.g. [1, 2, 3] or ["a", "b", "c"]).
When mixed data types are supplied in a vector, the formula language will try to convert all elements of the vector to a single type:
- If any element is
undefined, all values will be converted toundefined. - If any element is a string and there are no undefined elements, all values will be converted to strings.
- If any element is a number and there are no strings and no undefined elements, all values will be converted to numbers.
An empty vector ([]) contains no elements. It is considered undefined.
If a vector is supplied where a scalar value is expected, only the first element of the vector is considered. But some functions, like concat, max, min, c, are designed to work with vectors and will process all elements of the vector.
| Situation | Formula | Result | Comment |
|---|---|---|---|
| A vector of strings is supplied | GETvariable(["gender", "age"]) | male | Only the first element of the vector ("gender") is considered |
| A vector of strings is supplied | contains("foobar", ["FOO", "text", "BAR"]) | TRUE | Only the first element of the vector ("FOO") is considered. Comparison is case-insensitive |
| A vector of numbers is supplied | [1, 2, 3] * 5 | 5 | Only the first element of the vector (1) is considered |
| A vector of numbers is supplied | 5 + [1, 2, 3] | 6 | Only the first element of the vector (1) is considered |
| A vector of numbers is supplied | [1, 2, 3] / 5 | 0.2 | Only the first element of the vector (1) is considered |
| A vector of numbers is supplied | 2 ^ [3, 4, 5] | 8 | Only the first element of the vector (3) is considered |
| A vector of numbers is supplied | [1, 2, 3] == 1 | TRUE | Only the first element of the vector (1) is considered |
| A vector of numbers is supplied | [1, 2, 3] != 3 | TRUE | Only the first element of the vector (1) is considered |
| A vector of numbers is supplied | 5 < [1, 2, 7] | FALSE | Only the first element of the vector (1) is considered |
| A vector of numbers is supplied | TRUE & [1, 2, 3] | TRUE | Only the first element of the vector (1) is considered |
| A vector of numbers is supplied | 0 | [1, 2, 3] | TRUE | Only the first element of the vector (1) is considered |
| A vector of numbers is supplied | [1, 2, 3] + undefined | undefined | Because undefined is contagious |
| A vector of numbers is supplied | [1, 2, 3] == undefined | undefined | Because undefined is contagious |
| A vector of numbers is supplied | -[5, 99] | -5 | Only the first element of the vector (5) is considered |
| A vector of booleans is supplied | if([TRUE, FALSE], 5, 20) | 5 | Only the first element of the vector (TRUE) is considered |
| A vector of booleans is supplied | [TRUE, FALSE] + 1 | 2 | Only the first element of the vector (TRUE) is considered. Then it was forced to 1 |
| A vector of booleans is supplied | concat([TRUE, FALSE]) | "10" | Function works with vector of strings. TRUE is forced into "1", FALSE was forced to "0" |
| A vector of booleans is supplied | min([TRUE, FALSE]) | 0 | Function works with vector of numbers. TRUE is forced into 1, FALSE was forced to 0 |
| A vector with mixed data types is supplied | max(["text", TRUE, -5]) | 1 | Function can work with a vector. All elements are converted to strings, TRUE is converted to "1". Then all elements forced to numbers |
| A vector with mixed data types is supplied | if([TRUE, "text", 0], 5, 20) | 5 | All elements are converted to strings, TRUE is converted to "1". Only the first element of the vector ("1") is considered. Compare "1"!=0, it is TRUE |
| An empty vector is supplied | -[] | undefined | Because empty vector is undefined |
| An empty vector is supplied | [] - 5 | undefined | Because empty vector is undefined, and undefined is contagious |
| An empty vector is supplied | [] != 1 | undefined | Because empty vector is undefined, and undefined is contagious |
| An empty vector is supplied | max([], 5) | undefined | Because empty vector is undefined, and undefined is contagious |
| An empty vector is supplied | concat("a", [], "b") | undefined | Because empty vector is undefined, and undefined is contagious |
A vector with undefined is supplied | -[undefined, 1] | undefined | All elements of the vector were converted to undefined, and undefined is contagious |
A vector with undefined is supplied | [1, 2, undefined] * 5 | undefined | All elements of the vector were converted to undefined, and undefined is contagious |
A vector with undefined is supplied | TRUE | [1, “text”, badFunction(234)] | undefined | All elements of the vector were converted to undefined, and undefined is contagious |
| A vector has only one element | [8] == 8 | TRUE | Only the first element of the vector (8) is considered |
| Two vectors are supplied | [1, 2, 3] + [4, 5, 6] | 5 | Only the first elements of both vectors (1 and 4) are considered |
| Function can return a vector | if(TRUE, [1, 2, 3]) | [1, 2, 3] | Condition is TRUE |
| Function can return a vector | if(TRUE, [1, 2, 3]) + 5 | 6 | Function if() returns a vector. Only the first element of the vector (1) is considered for addition |
| Function works with scalar only | [1, "anything"] == [1, "different"] | TRUE | Only the first element in both vectors (1) is considered |
| Function works with scalar only | [1, undefined] == [1, undefined] | undefined | Because undefined is contagious |
| Function works with scalar only | [1, "a"] != [1, "b"] | FALSE | Only the first element in both vectors (1) is considered |
| Function works with scalar only | [2, 99] == [3, 99] | FALSE | Only the first element in both vectors (2 and 3) are considered |
| Function works with scalar only | 1 == [1, 2, 3] | TRUE | Only the first element of the vector (1) is considered |
| Function works with scalar only | [1, 2, 3] == [1, 2, 3, 4, 5] | TRUE | Only the first element in both vectors (1) is considered |
| Function can work with vectors | max([1, 7, 20], 5, [3, 15]) | 20 | 20 is the biggest value from: 1, 7, 20, 5, 3, 15 |
| Function can work with vectors | min([1, "text", TRUE], 5, [3, 15]) | 0 | "text" is forced into 0, and this is the smallest value from: 1, 0, 1, 5, 3, 15 |
| Function can work with vectors | concat(["a", "b"], "c") | "abc" | Concatenation is performed on all elements of vector and on other scalar argument |
If function can work with a vector (takes all elements), it can work with nested vector as well. If not, only first element from nested vector is considered. Note, that rule of type conversion for mixed data types is applied first.
| Situation | Formula | Result | Comment |
|---|---|---|---|
| Function expects only scalar | [[1, 10, 100], 2, 3] * 5 | 5 | Only the first element ([1, 10, 100]) is considered. Since it is a vector, take only its first element (1) |
| Function expects only scalar | contains("foobar", [["text", "bar"], "foo", "foobar"]) | FALSE | Only the first element (["text", "bar"]) is considered. Since it is a vector, take only it’s first element ("text") |
| Function expects only scalar | contains("foobar", ["foo", ["text", "bar"], "text"]) | TRUE | Only the first element ("foo") is considered |
| Function expects only scalar | [[1,2],3] < [2,1,3] | TRUE | Comparison works for scalars. Only the first elements of the vectors ([1, 2] and 2) are considered. Since one of them is a vector, take only its first element (1) |
| Function can work with vectors | max([1, 7, [20, 50, 70]], 5, [3, 15]) | 70 | 70 is the biggest value from: 1, 7, 20, 50, 70, 5, 3, 15 |
| Function can work with vectors | min([1, 2, [TRUE, FALSE]], 5, [3, 15]) | 0 | FALSE is forced into 0, and this is the smallest value from: 1, 2, 1, 0, 5, 3, 15 |
| Function can work with vectors | min([1, 2, [TRUE, undefined]], 5, [3, 15]) | undefined | Because undefined is contagious |
A vector is displayed in a survey (and passed in redirects) as a comma-separated list of values. For example, [1, 2, 3] is displayed as 1,2,3.
c
The function c(x) can be used to form a vector. It is equivalent to the [...] notation.
This function can process up to 500 arguments maximum. If more are provided, only the first 500 are considered.
Signature: c(x, ...)
Examples:
| Formula | Result | Comment |
|---|---|---|
c(25) | 25 | Single argument is provided. Result is a scalar |
c(12,123,"23") | ["12","123","23"] | All elements are forced to strings |
c(12,TRUE,"text") | ["12","1","text"] | All elements are forced to strings |
c(12,TRUE,25) | [12, 1, 25] | All elements are forced to numbers |
c(12,badFunction(234),25) | [undefined, undefined, undefined] | Because badFunction returns undefined. All vector’s elements were converted to undefined |
c() | undefined | Function forms an empty vector, and empty vector is undefined |
Not yet implemented: The operator @
The operator @ is used to check if a value is present in a vector. It returns TRUE if the value is present and FALSE if it is not.
Signature: needle @ stack, where needle is the value to check and stack is the vector to check in.
Both needle and stack can be of any type. The following rules apply:
- If either
needleorstackis undefined (or any element of theirs is undefined), the result of the operator isundefined. - If either
needleorstackare strings (or vectors of strings), both operands are converted to strings (or vectors of strings). - If either
needleorstackare numbers (or vectors of numbers) and there are no strings and no undefined values, both operands are converted to numbers (or vectors of numbers). - If
needleis a vector, the operator returnsTRUEif at least one element of theneedlevector is present in thestackvector.
Examples:
| Formula | Result | Comment |
|---|---|---|
2 @ [1, 2, 3] | TRUE | 2 is present in the vector |
4 @ [1, 2, 3] | FALSE | 4 is not present in the vector |
"b" @ ["a", "b", "c"] | TRUE | “b” is present in the vector |
"d" @ ["a", "b", "c"] | FALSE | |
2 @ c(1, "2", 3) | TRUE | 2 is converted to “2” and is present in the vector |
c(1, 2, 3) @ c(4, 5, 2) | TRUE | 2 is present in both vectors |
c(1, 2, 3) @ c(4, 5, 6) | FALSE | No common elements in the vectors |
c(TRUE, FALSE) @ TRUE | TRUE | The TRUE from the needle is present in the stack vector |
c(TRUE, FALSE) @ 5 | FALSE | c(TRUE, FALSE) is converted to [1, 0] and neither 1 nor 0 is present in the stack 5 |
c(TRUE, FALSE, "5") @ 5 | TRUE | c(TRUE, FALSE, "5") is converted to ["1", "0", "5"] and 5 is converted to "5" |
"Big" @ topLevel(123,2)(for a respondent who was only choosing the “Big” level in that attribute) | TRUE | “Big” is present in the vector of top 2 levels for attribute with ID 123 |
["Big","Medium"] @ topLevel(123,2)(for a respondent who was only choosing the “Big” level in that attribute) | TRUE | “Big” is present in the vector of top 2 levels for attribute with ID 123 |