HISE Docs

Array

The array is the default container type in HiseScript for holding multiple elements that can be accessed by their index. There are a few other container types which are better suited for particular workflows (see the section about Alternatives below), but for general data processing this is one of the most important concepts to know about.

Basic usage

const var a = [];         // Declare an array
a[0] = 12;                // Set the element at position 0 to 12
a[1] = "Hello";           // Set the element at position 1 to "Hello"
Console.print(a.length);  // Print the length (in this case 2)
a.clear();                // Deletes all items from the array


If you have used another programming language before, this might look pretty familiar. Be aware that you can add / delete items from the array despite having it declared as const var . The "constness" just refers to the assignment, so you can't reassign this variable to another value.

Iterating over an array

Basically there are two ways of iterating (= going over each element in the array):

Range-based Loop Index-based Loop
for(element in array) for(i = 0; i < array.length; i++)
This is the preferred method, because it has a clearer syntax (and is faster). As long as you don't need to know the index of the element, it's recommended to use this method. If you need the index of the current item in the loop (eg. because you iterate over multiple arrays at once), use this loop.

The index based loop construct is the only place where you can define anonymous variables (so that for(i = 0... doesn't throw a compile error).

Ownership & lifetime

An array is reference counted, which means that if you assign an array to another variable, it will use the same array.

const var a = [1, 5, 6];
const var b = a;

a[0] = 10;           // set the first element of a
Console.print(b[0]); // the first element of b will also be 10

Alternatives

The Array is a very dynamic container type and can be resized at any time to make room for more elements. For UI and data processing this is an incredibly useful feature. However this flexibility makes it a very poor choice for whenever you want to do some MIDI processing logic which usually runs in the audio callback where allocating new memory is a no go.

In order to mitigate this problem, there are a bunch of other container types similar to the stock Array but with an emphasis on certain tasks within the realtime callback:

If you don't want to use those containers, you can of course use the Array in the MIDI processing context as long as you don't resize the container (which is why the Array.reserve() function is so importanta).


Class methods

clear

Clears the array.

Array.clear()


This is a quick operation (the allocated storage space will not be freed), so you can use it in a realtime callback.

const var arr = []; // Declare an array

// preallocate 10 elements, do this if you
// know how many elements you are about to insert
arr.reserve(10); 

for(i = 0; i < 10; i++)
{
	// Add an element to the end of the array
	arr.push(Math.randInt(0, 1000);
}

Console.print(trace(arr)); // [ 523, 5, 76, 345, 765, 45, 977, 223, 44, 54]

arr.clear();

Console.print(trace(arr)); // []


concat

Concatenates (joins) two or more arrays

Array.concat(var argumentList)


This method combines two or more arrays. You can pass in any number of arrays which will be put at the end of the array. It ignores non-array argument elements.

const var arr1 = [0, 1, [2, 3, 4]];

// note how the array in the array is counted as a single element
Console.print(arr1.length); // 3    

const var arr2 = [5, 6, 7];
const var arr3 = [8, 9, 10];

arr1.concat(arr2);
Console.print(trace(arr1)); // [0, 1, [2, 3, 4], 5, 6, 7]

arr1.concat(arr3);

// the arr1 already contains arr2 
Console.print(trace(arr1)); // [0, 1, [2, 3, 4], 5, 6, 7, 8, 9, 10]     


// set type to array
const var arr4 = []; 
arr4.concat(arr2, arr3, 8726, [11, 12, 13]);

// non-array arguments get ignored // arguments can be arrays themselves
Console.print(trace(arr4)); // [5, 6, 7, 8, 9, 10, 11, 12, 13]


contains

Searches for the element in the array.

Array.contains(var elementToLookFor)


The Array.contains method checks if an array includes a certain element. If the array contains the specified element, it returns true ,
otherwise it returns false .
elementToLookFor is the element to search for within the array.

Example

const var fruits = ["apple", "banana", "mango", "orange"];

Console.print(fruits.contains("banana")); // true
Console.print(fruits.contains("grape"));  // false


find

Returns the value of the first element that passes the function test.

Array.find(var testFunction, var optionalThisObject)


The test function you pass in can have up to 3 parameters:

const var list = [ "Hello", "world", "HISE", "rules" ];

Console.print(list.find(function(element){ return element.contains("H");})); // Hello
Console.print(list.find(function(element){ return element.contains("HI");})); // HISE

Using this function can vastly decrease the amount of code you need to write. This is the same logic of the first call with a loop and a custom function to achieve the same thing.

const var list = [ "Hello", "world", "HISE", "rules" ];

function findH()
{
	for(element in list)
	{
		if(element.contains("H"))
			return element;
	}
	
	return undefined;
}

Console.print(findH()); // Hello


indexOf

Searches the array and returns the first index.

Array.indexOf(var elementToLookFor, int startOffset, int typeStrictness)


Return the index of the first occurence or -1 if the item can't be found.

const var a = [1, 5, 5];
a.indexOf(5); // will return 1
a.indexOf("5"); // will also return 1, the search is not type-strict.


insert

Inserts the given arguments at the firstIndex.

Array.insert(int firstIndex, var argumentList)


The Array.insert method allows you to add an element at a specified firstIndex in the array. It modifies the original array and shifts the elements after the specified index to the right allowing for greater control over the array's structure than using Array.push or setting the element using the [] -operator.

Note that if you pass in an Array as new element, it will add the element as an array and not the individual elements, so you'll end up with an Array within an Array.

Example

const var numbers = [1, 2, 3, 4, 5];

numbers.insert(2, 10);
Console.print(trace(numbers)); // [1, 2, 10, 3, 4, 5]

numbers.insert(0, 20);
Console.print(trace(numbers)); // [20, 1, 2, 10, 3, 4, 5]

numbers.insert(numbers.length, 30);
Console.print(trace(numbers)); // [20, 1, 2, 10, 3, 4, 5, 30]

numbers.insert(3, [101, 102, 103]);
Console.print(trace(numbers));


isArray

Checks if the given variable is an array.

Array.isArray(var variableToTest)


A simple bool check whether the argument variable is an Array. Note that this function is not a method that you call on the object itself (because calling it on a non-array would not find the function). Instead you'll call it with the generic syntax Array.isArray()

const var trustMeIAmAnArray = 0;
const var notAnArrayTooButNiceTryString = "[1, 2, 3, 4, 5]";
const var list = [1, 2, 3, 4];

Console.print(Array.isArray(notAnArrayTooButNiceTryString)); // false;
Console.print(Array.isArray(trustMeIAmAnArray)); // false
Console.print(Array.isArray(list)); // true (finally)


join

Joins the array into a string with the given separator.

Array.join(var separatorString)


This method is useful when you want to change the item list of some UI controls, for example a Combobox .

const var list = ["item1", "item2", "item3"];     // Creates a list of all available samplemaps
const var box = Content.addComboBox("box", 0, 0); // Creates a combobox
box.set("items", list.join("\n"));                // sets the list as items

The opposite of this method is String.split()

map

Creates a new array from calling a function for every array element.

Array.map(var testFunction, var optionalThisObject)



pop

Removes and returns the last element.

Array.pop()


This is useful for managing sequential input that you're keeping track of: history of played notes, velocities, custom undo history etc.

You might want to use it in conjunction with Array.push() in order to implement a stack logic with the array.

Note that there's a special container type if you need a stack that doesn't care about the order of elements.

const arr1 = [1, 2, 3];
arr1[4] = 5;

Console.print(arr1.pop()); // 5

// we didn't set the 4th element (index 3) so it'll be undefined
Console.print(arr1.pop()); // error: API call with undefined parameter 

arr1[3] = 22;
Console.print(trace(arr1)); // [1, 2, 3, 22]

// we can check ourselves for errors in our logic in this case
if (isDefined(arr1.pop() 
{
    // do stuff
}


push

Adds the given element at the end and returns the size.

Array.push(var elementToInsert)


If you know that you are going to add multiple elements, you can call Array.reserve() to preallocate the amount of elements and improve performance:

const var a = [];

// Uncomment this to see the performance improvement:
//a.reserve(100);

Console.start();
for(i = 0; i < 100; i++)
{
    a.push(5);
}
Console.stop()


pushIfNotAlreadyThere

Adds the given element at the end and returns the size.

Array.pushIfNotAlreadyThere(var elementToInsert)



remove

Removes all instances of the given element.

Array.remove(var elementToRemove)



removeElement

Removes the element at the given position.

Array.removeElement(int index)



reserve

Reserves the space needed for the given amount of elements.

Array.reserve(int numElements)


If you are going to populate this array in a realtime callback, you need to make sure that there is enough storage allocated in order to avoid reallocation. This method can be used to preallocate slots that can be filled later.

Be aware that this method will not change the Array.length property:

const var array = [];       // create a new array
array.reserve(128);         // allocate 128 items
Console.print(array.length) // will output 0;
array[64] = 190;            // this will not allocate
Console.print(array.length) // will print 65


This method will allocate enough memory to hold primitive values, but if you are going to store complex objects (arrays or objects), calling Array.reserve() will not prevent reallocation.

reverse

Reverses the order of the elements in the array.

Array.reverse()



sort

Sorts the array.

Array.sort()


This will sort the array using a sensible sort algorithm:

const var a = [1, 6, 4, 2, 1];
a.sort();

for(i in a)
    Console.print(i); 

// Result: 1, 1, 2, 4, 6


sortNatural

Sorts array of numbers, objects, or strings with "number in string" priority. Can also sort a combination of all types

Array.sortNatural()