---
title: "Text and collections"
description: "TapHome scripting text and collection functions: LENGTH, GETAT, SETAT, APPEND, INSERT, REMOVEAT, COPY, INDEXOF, REPLACE, SPLIT, COMPARE and BYTECOLLECTION, UINT16COLLECTION, BOOLCOLLECTION."
url: "https://taphome.com/en/docs/script/text-string-and-byte-array/"
language: en
lastmod: 2026-11-06
generator: hugo
ai:
  topics: ["string-functions","byte-array","collections","scripting-language"]
  questions: ["How do I get the length of a string in TapHome script?","How to split a string by a separator in TapHome?","How do I replace text within a string in TapHome?","How to create a byte collection from hexadecimal values?","How to find the index of an element in a string or collection?","Does APPEND create a new collection or change the original one?","How do I compare two strings in a TapHome script?"]
---

# Text and collections

TapHome script functions for strings, collections and byte arrays — LENGTH, GETAT, SETAT, APPEND, INSERT, REMOVEAT, COPY, INDEXOF, REPLACE, SPLIT, COMPARE, BYTECOLLECTION, UINT16COLLECTION, BOOLCOLLECTION.

Last updated: 2026-11-06

These functions take a string or a collection as the first argument and work with characters or elements by a zero-based index.

- A **collection** is changed **in place** by `APPEND`, `INSERT`, `REMOVEAT`, `SETAT` and `REPLACE`, which return the same collection. For a **string** they return a new string.
- A **blob**, such as `RECEIVEDMSG.PAYLOAD`, is accepted only by `LENGTH`, `GETAT`, `COPY` and `INDEXOF`.
- A `Null` first argument stops the script with *Parameter 1 is null*, except in `LENGTH` (0), `INDEXOF` (-1) and `SPLIT` (an empty collection); `COMPARE` reports *COMPARE arguments 1 and 2 must be strings*.

`ENCODE` and `DECODE` (XML, Base64) are on [Data type conversions](https://taphome.com/en/docs/script/data-type-conversions/), `EQUALS` on [Logic and diagnostics](https://taphome.com/en/docs/script/logic-and-diagnostics/#equals). Collection types are described in [Data types](https://taphome.com/en/docs/script/data-types/).

## LENGTH

`LENGTH` returns the number of characters of a string, elements of a collection or bytes of a blob; for a number it returns the size of its type in bytes, and for `Null` 0.

```taphome
# characters in a string
LENGTH("Hello World");
# Result: 11
# length of a number
LENGTH(40);
# Result: 8 (a decimal literal is a double)
# bytes in a byte collection
LENGTH(BYTECOLLECTION("010203"));
# Result: 3
```

## GETAT

`GETAT` returns the element at an index: a `char` of a string, an element of a collection or a byte of a blob.

```text
GETAT(value, index)
```

**Returns** — for a string a `char`, not a one-letter string; compare it with a char literal such as `'l'`.

```taphome
GETAT("Hello", 2);
# Result: 'l' (Char)
GETAT({1, 2, 4}, 2);
# Result: 4
```

## SETAT

`SETAT` replaces the element at an index; a collection is changed in place, for a string the character at the index is replaced by the text of `newValue`.

```text
SETAT(value, index, newValue)
```

```taphome
# replace one character
SETAT("Hello", 1, "a");
# Result: "Hallo"
# replace a character with longer text
SETAT("Hello", 4, "o World");
# Result: "Hello World"
# a collection to change
VAR c := {1, 2, 4};
# replace an element in place
SETAT(c, 2, 3);
# Result: {1, 2, 3}, and c is now {1, 2, 3}
```

## APPEND

`APPEND` adds a value to the end of a string or a collection; a collection is changed in place and returned, not copied.

```text
APPEND(value, what)
```

**Remarks** — Appending a collection with the same element type adds all its elements. A single value is added as one element. A collection of another element type is an error (*Cannot append 'UInt8' collection to 'Double' collection*).

```taphome
# a collection to extend
VAR c := {1, 2};
# add one element in place
APPEND(c, 3);
# Result: {1, 2, 3}, and c is now {1, 2, 3}
# add several elements in place
APPEND(c, {4, 5});
# Result: {1, 2, 3, 4, 5}
# append text to a string
APPEND("abc", "def");
# Result: "abcdef"
```

## INSERT

`INSERT` inserts a value at an index: a substring into a string, or an element into a collection in place.

```text
INSERT(value, index, what)
```

```taphome
# insert a substring
INSERT("Hello", 5, " World");
# Result: "Hello World"
# insert a character
INSERT("Hello", 1, "i");
# Result: "Hiello"
# insert an element into a collection
INSERT({1, 2, 4}, 2, 3);
# Result: {1, 2, 3, 4}
```

## REMOVEAT

`REMOVEAT` removes `count` characters or elements, 1 by default, starting at an index.

```text
REMOVEAT(value, index)
REMOVEAT(value, index, count)
```

```taphome
# remove one character
REMOVEAT("Hello", 1);
# Result: "Hllo"
# remove 2 characters from index 3
REMOVEAT("Hello", 3, 2);
# Result: "Hel"
# remove 2 elements from a collection
REMOVEAT({1, 2, 3, 4}, 2, 2);
# Result: {1, 2}
```

## COPY

`COPY` returns a new string, collection or blob with `length` items starting at `from`; without `length` it copies to the end, without `from` the whole value.

```text
COPY(value)
COPY(value, from)
COPY(value, from, length)
```

```taphome
# copy from index 2 to the end
COPY("Hello World", 2);
# Result: "llo World"
# copy 4 characters from index 2
COPY("Hello World", 2, 4);
# Result: "llo "
# copy 1 byte from a blob
COPY(BYTECOLLECTION("01020304"), 2, 1);
# Result: {0x03}
```

**Errors** — *Parameter 1 must be a non-empty string* when copying from an empty string.

## INDEXOF

`INDEXOF` returns the position of the first occurrence of a value in a string, a collection or a blob, or `-1` when it is not found.

```text
INDEXOF(value, what)
```

```taphome
# position of a substring
INDEXOF("Hello World", "Wor");
# Result: 6
# not found gives -1
INDEXOF("Hello World", "or12");
# Result: -1
# position of an element in a blob
INDEXOF(BYTECOLLECTION("ab cd ee ff 01 02"), 2);
# Result: 5
```

**Errors** — *Parameter 2 must be a non-empty string* when searching a string for an empty string.

## REPLACE

`REPLACE` replaces every occurrence of a value: a string gives a new string, a collection has its matching elements replaced in place.

```text
REPLACE(value, what, replacement)
```

```taphome
# remove every l
REPLACE("Hello", "l", "");
# Result: "Heo"
# replace a substring
REPLACE("Hello", "lo", "22");
# Result: "Hel22"
# replace an element in a blob
REPLACE(BYTECOLLECTION("050607"), 5, 9);
# Result: {0x09, 0x06, 0x07}
```

**Errors** — *Empty string to replace* when `what` is an empty string.

## SPLIT

`SPLIT` splits a string at every separator and returns a `collection<string>`; empty parts are kept.

```text
SPLIT(string, separator)
```

**Parameters** — `separator` is a `char`, a string, a `collection<char>` or a `collection<string>`.

```taphome
# split at a separator
SPLIT("1;2;3;4", ";");
# Result: {"1", "2", "3", "4"}
# separator longer than one character
SPLIT("1;2;3.4", "2;");
# Result: {"1;", "3.4"}
# several separators at once
SPLIT("1;2;3.4", {"2", "3."});
# Result: {"1;", ";", "4"}
```

## COMPARE

`COMPARE` compares two strings and returns a negative number when the first sorts before the second, 0 when they are equal and a positive number when it sorts after; rely on the sign only, not on the size.

```text
COMPARE(string1, string2)
COMPARE(string1, string2, CompareOptions)
```

**Remarks** — Without options a control unit returns the difference of the character codes of the first differing characters, so uppercase letters sort before lowercase ones. With `CompareOptions` (`IgnoreCase`, `IgnoreNonSpace`, `IgnoreSymbols`, `IgnoreKanaType`, `IgnoreWidth`, `OrdinalIgnoreCase`, `StringSort`, `Ordinal`, `None`) the strings are compared by the linguistic rules of the invariant culture, the same on every control unit, adjusted by those options.

```taphome
# equal strings give 0
COMPARE("abc", "abc");
# Result: 0
# different case gives a positive number
COMPARE("abc", "ABC");
# Result: 32
# first string sorts before the second
COMPARE("a", "c");
# Result: -2
# ignoring case gives 0
COMPARE("abc", "ABC", CompareOptions.IgnoreCase);
# Result: 0
```

**Errors** — *COMPARE arguments 1 and 2 must be strings*.

## BYTECOLLECTION

`BYTECOLLECTION` creates a `collection<uint8>`, either from a string of hexadecimal digits or filled with a given number of zero bytes (1 – 2048).

```text
BYTECOLLECTION(hexString)
BYTECOLLECTION(count)
```

**Remarks** — Characters of the string that are not hexadecimal digits are ignored, so spaces, commas and dashes can separate the bytes; the number of remaining digits must be even.

```taphome
# bytes from hex text
BYTECOLLECTION("00 0A FF");
# Result: {0x00, 0x0A, 0xFF}
# hex text with mixed separators
BYTECOLLECTION("aa, be1-1,fe");
# Result: {0xAA, 0xBE, 0x11, 0xFE}
# a number gives that many zero bytes
BYTECOLLECTION(6);
# Result: 6 zero bytes
```

**Errors** — *Parameter must be a non-empty string*; *Length must be a multiple of 2*; *Maximum array length is 2048*; *Invalid array length. Must be greater than 0 and less than or equal 2048*.

## UINT16COLLECTION

`UINT16COLLECTION` creates a `collection<uint16>` of 1 – 2048 zeros, typically filled with `PACKVALUE` and written to Modbus registers with `MODBUSWBLOCK`.

```taphome
collection<uint16> regs := UINT16COLLECTION(4);
PACKVALUE(regs, 0, BigEndianFloat, 21.5);
PACKVALUE(regs, 2, Uint16, 100);
MODBUSWBLOCK(H, 200, regs);
```

**Available** — TapHome Next 2026.1.39016+.

**See also** — [Binary data](https://taphome.com/en/docs/script/binary-data/), [Modbus functions](https://taphome.com/en/docs/script/modbus/).

## BOOLCOLLECTION

`BOOLCOLLECTION` creates a `collection<bool>` of 1 – 2048 `FALSE` values, typically for writing Modbus coils with `MODBUSWBLOCK`.

```taphome
collection<bool> coils := BOOLCOLLECTION(8);
SETAT(coils, 0, TRUE);
MODBUSWBLOCK(C, 0, coils);
```

**Available** — TapHome Next 2026.1.39016+.
