Product SiteDocumentation Site

11.3.6. Collections

A "collection" is just that - a collection of Objects. Collections are simply a means of organizing a large amount of data, without having to assign a variable name for each portion of data. Compared to other programming languages, SuperCollider provides a relatively large number of Collections in the standard library.
We have already seen an example of a Collection as multichannel audio arrays. An Array is a kind of Collection - in object-oriented terminology, the Array Class is a sub-class of the Collection Class, and inherits its behaviours. Conversely, the Collection Class is the super-class of the Array Class. The Collection Class itself is not to be used; it is designed to provide common features so that it is easier to write Classes for collections.
As with all the chapters from this point on, it is not necessary to read this in sequence. If you prefer, you can skip it and return later when you need to manage a large set of data.

11.3.6.1. Array

Arrays have been traditionally been very popular with programmers. In SuperCollider, they are capable of storing a large number of Objects, and they provide advanced behaviours that are normally not associated with Arrays. They are not as indespensible as they used to be. Most programming languages now provide (or can easily be extended to add) Lists, Trees, and other kinds of data storage structures, which offer more capabilities, and are easier to use and to think about. Users new to programming might find the various kinds of Lists to be more helpful.
11.3.6.1.1. Building an Array
An Array is a Collection with a finite maximum size, determined at declaration time. It is the programmer's responsibility to maintain a meaningful order, and to remember the meaning of the data. Data in an Array is called "elements," each of which is assigned a specific "index number." Index numbers begin at 0. Any mix of Objects can be stored in an Array, including an Array.
This example declares an Array, adds some elements, then prints them out.
(
   var tA = Array.new( 2 ); // "tA" stands for "testArray"

   tA = tA.add( 5 );
   tA = tA.add( 3 );
   tA = tA.add( 17 );

   tA.postln;
   nil;
)
Notice that Array is a Class, and it must be instantiated before use. Here, the variable tA is assigned an Array with enough space for two objects. Notice that the elements are printed out in the order that you add them to the Array. They are not sorted or shuffled (unless you send a message like scramble). But why did I write tA = tA.add( 17 ); instead of tA.add( 17 );? Shouldn't the second method be sufficient for adding an Object to an Array, thereby making the re-assignment unnecessary? It does, but let's see what happens when we take it away:
(
   var tA = Array.new( 2 ); // "tA" stands for "testArray"

   tA.add( 5 );
   tA.add( 3 );
   tA.add( 17 );

   tA.postln;
   nil;
)
The 17 is missing - it doesn't get added into the Array! This is because the Array was only declared with two slots, and you can't add three Objects into two slots. So why did this work the first time? SuperCollider was programmed to help us fit additional items into an Array. If an Array has reached its capacity, SuperCollider will automatically make a new, larger Array for us, and returns that from the add method. Therefore, any time you add an element to an Array, you should always re-assign the result, so that you don't have to worry about whether you exceeded the Array's capacity.
11.3.6.1.2. Accessing an Array's Elements
There are two ways to access individual elements within an Array. One way is object-oriented, and one way is more traditional, inspired by programming languages such as the wildly popular "C" language. The object-oriented style uses the at and put methods. The traditional style uses square brackets with an index number.
The following examples produce equivalent output. The first uses the object-oriented style, and the second uses the traditional style.
(
   var tA = Array.new( 3 );

   tA = tA.add( 5 );
   tA = tA.add( 3 );
   tA = tA.add( 17 );

   tA.at( 0 ).postln; // outputs 5
   tA.at( 1 ).postln; // outputs 3
   tA.at( 2 ).postln; // outputs 17

   tA.put( 0, 24 ); // assigns 24 to element 0

   tA.at( 0 ).postln; // outputs 24

   nil;
)
(
   var tA = Array.new( 3 );

   tA = tA.add( 5 );
   tA = tA.add( 3 );
   tA = tA.add( 17 );

   tA[0].postln; // outputs 5
   tA[1].postln; // outputs 3
   tA[2].postln; // outputs 17

   tA[0] = 24 ; // assigns 24 to element 0

   tA[0].postln; // outputs 24

   nil;
)
Different people prefer different styles of accessing Arrays.