Difference between revisions of "Reference Talk:Array"
Jholsenback (talk | contribs) m (corrections and layout) |
Jholsenback (talk | contribs) m (fixed syntax diagram typos) |
||
Line 25: | Line 25: | ||
<pre> | <pre> | ||
DICTIONARY_DECLARATION: | DICTIONARY_DECLARATION: | ||
− | # | + | #declare | #local IDENTIFIER = dictionary; | |
− | # | + | #declare | #local IDENTIFIER = dictionary DICTIONARY_INITIALIZER |
DICTIONARY_INITIALIZER: | DICTIONARY_INITIALIZER: | ||
{DICTIONARY_ITEM, [DICTIONARY_ITEM, ]... } | {DICTIONARY_ITEM, [DICTIONARY_ITEM, ]... } |
Revision as of 16:49, 23 November 2016
You may declare arrays of identifiers with up to five dimensions. Any item that can be declared as an identifier can be declared in an array. A New feature in version 3.7.1 extends array
functionality to allow the creation of dictionary
container types. Dictionaries can support mapping string keys to arbitrary-type values.
Declaring Arrays
The syntax for declaring an array
is as follows:
ARRAY_DECLARATION: #declare IDENTIFIER = array[ INT ][[ INT ]]..[ARRAY_INITIALIZER] | #local IDENTIFIER = array[ INT ][[ INT ]]..[ARRAY_INITIALIZER] ARRAY_INITIALIZER: {ARRAY_ITEM, [ARRAY_ITEM, ]... } ARRAY_ITEM: RVALUE | ARRAY_INITIALIZER
The syntax for declaring a dictionary
is as follows:
DICTIONARY_DECLARATION: #declare | #local IDENTIFIER = dictionary; | #declare | #local IDENTIFIER = dictionary DICTIONARY_INITIALIZER DICTIONARY_INITIALIZER: {DICTIONARY_ITEM, [DICTIONARY_ITEM, ]... } DICTIONARY_ITEM: ["STRING"]: DICTIONARY_ENTRY | .STRING_IDENTIFIER: DICTIONARY_ENTRY DICTIONARY_ENTRY: Any valid array entry
Where IDENTIFIER is the name of the identifier and INT is a valid float expression, internally truncated to an integer, and used to specify the size of the array.
Note: In previous versions IDENTIFIER names were limited to 40 characters. There has been a Change that removes than restriction.
See Array Initializers for more about the optional ARRAY_INITIALIZER parameter.
Here is an example of a one-dimensional, uninitialized array:
#declare MyArray = array[10]
It declares an uninitialized array of ten elements. The elements are referenced as MyArray[0]
through MyArray[9]
. As yet, the type of the elements are undetermined. Once you have initialized any element of the array, all other elements can only be defined as that type.
An attempt to reference an uninitialized element results in an error. See the following:
#declare MyArray = array[10] #declare MyArray[5] = pigment{White} //all other elements must //be pigments too. #declare MyArray[2] = normal{bumps 0.2} //generates an error #declare Thing = MyArray[4] //error: uninitialized array element
Multi-dimensional arrays up to five dimensions may be declared. This example ...
#declare MyGrid = array[4][5]
... declares a 20 element array of 4 rows and 5 columns. Elements are referenced from MyGrid[0][0]
to MyGrid[3][4]
. Although it is permissible to reference an entire array as a whole, you may not reference just one dimension of a multi-dimensional array.
#declare MyArray = array[10] #declare MyGrid = array[4][5] #declare YourArray = MyArray //this is ok #declare YourGrid = MyGrid //so is this #declare OneRow = MyGrid[2] //this is illegal
The #ifdef
and #ifndef
directives can be used to check whether a specific element of an array has been declared. For methods to determine the size of an array look in the float section for dimensions
and
dimension_size
.
Large uninitialized arrays do not take much memory. Internally they are arrays of pointers so they probably use just 8 bytes per element. Once initialized with values, they consume memory depending on what they contain.
The rules for local vs. global arrays are the same as any other identifier.
Note: This applies to the entire array. You cannot mix local and global elements in the same array. See #declare vs. #local for information on identifier scope.
Any legitimate use of the #declare
directive can also be put into an array. In other words, you can also create multidimensional arrays by making an array of arrays.
When declaring dictionaries be aware of the following:
- Array elements will no longer have to be all of the same type. Caveats listed below:
- Mixing elements of different types will increase memory consumption
- The increased memory footprint will not revert even if the array is later set to elements all of the same type
- An array can be declared without specifying any dimensions; in this case the array will be one-dimensional and be able to grow in size dynamically
- Accessing an element beyond the nominal size of such an array will automatically increase the nominal size just enough to include that element. Caveats listed below:
- The memory footprint may be twice as high than required for the current nominal size.
- Growth of such an array is triggered by any access to an element beyond the nominal size
- This includes tests such as
#ifdef(ARRAY[INDEX])
- When using square bracket notation, the keys do not necessarily have to be string literals, but can be arbitrary string expressions
- When using dot notation, the indices must follow the generic rules for identifiers
- When using square bracket notation, the keys do not necessarily have to be string literals, but can be arbitrary string expressions
Here are some usage examples:
// create an empty dictionary #declare Fnord = dictionary; // create a dictionary with elements #declare Fnord = dictionary { ["Foo"]: 42, ["Bar"]: sphere { <0,0,0>, 1 } } // alternative #declare Fnord = dictionary { .Foo: 42, .Bar: sphere { <0,0,0>, 1 } } // access a dictionary element #declare Fnord["Foo"] = 42; #declare Answer = Fnord["Foo"]; // alternative #declare Fnord.Foo = 42; #declare Answer = Fnord.Foo; // testing whether a dictionary contains a particular key #ifdef (Fnord["Foo"]) ... #end #declare FooKeyExists = defined(Fnord.Foo); // removing a key from a dictionary #undef Fnord["Foo"];
Array Initializers
Because it can be cumbersome to individually initialize the elements of an array, you may initialize it as it is created using array
initializer syntax.
#include "colors.inc" #declare FlagColors = array[3] {Red,White,Blue}
Multi-dimensional arrays may also be initialized this way.
#declare Digits = array[4][10] { {7,6,7,0,2,1,6,5,5,0}, {1,2,3,4,5,6,7,8,9,0}, {0,9,8,7,6,5,4,3,2,1}, {1,1,2,2,3,3,4,4,5,5} }
The commas are required between elements and between dimensions as shown in the example.