Array Values

An array is a variable length indexable sequence of values. The values in an array can be of any type. Array values are mappable.

Literals

#(<value>, <value>, ...)

#()                      -- an empty array

See also Array Literals.

Constructors

<collection> as array

Convert collection to an array.

Properties

<array>.count            : Integer, read-only

Returns number of elements in array.

Operators

<array>[<integer>]

Returns element of array. Indexes start at 1.

<array>[<integer>] = <value>

Sets element of array to value, growing array as necessary.

<array> + <collection>

Like join except a completely new array is constructed containing all the elements of the first and second operands

Example:

a = #(1,2,3,4)

join a #(5,6,7,8)

(cameras as array) + lights

props = getPropNames Node

join props getPropNames (classOf $foo)

join props getPropNames $foo $dynamicOnly

sort props

Methods

append <array> <value>

Append value to array, growing it as necessary.

copy <array> [#noMap]   -- mapped

Creates a copy of all the elements in the array. Returns a value of OK. If #noMap is specified, the copy made is what is called a shallow copy - only a copy of the upper-level value itself (that is, the array value) is created. Copies aren't made of values stored in the array, rather a reference to the same value is stored in both array values.

deleteItem <array> <number>

Delete element indexed by number from array, shrinking it in size by 1.

join <array> <collection>

Appends all the elements of the second argument to the array (first) argument.

sort <array>

Sorts the elements of the array into ascending order. All the elements must be comparable.

findItem <array> <value>

Does a MAXScript '==' comparison between elements in the array and the target object and then returns the index of the first occurrence of the given value in the array or zero if the value is not in the array.

Values such as Point3s and Strings match if they have the same contents.

insertItem <value> <array> <integer>

Inserts the value at the specified index in the array, growing the array if necessary

qsort <array> <function> [start:<integer>] [end:<integer>] [user-defined key args passed to function]

Sorts the array using the specified function for element-by-element comparison. The comparison function must take 2 values as arguments, and return a number < 0 if the first value is less than the second value, 0 if the values are equivalent, and a number > 0 if the first value is greater than the second value. The entire array is sorted unless a start or end value is specified.

For example, the following script generates 10 random positions, and then sorts the positions based on their distance from [0,0,0]:

positions=for i=1 to 10 collect (random [0,0,0] [100,100,0])

qsort positions (fn distFrom0 v1 v2 = (length v1)-(length v2))

All key arguments are now passed to the comparison function. This allows you to do things like an indexed sort:

fn compareFN v1 v2 valArray: =

(

local v1i = valArray[v1]

local v2i = valArray[v2]

(length v1i)-(length v2i)

)

positions=for i=1 to 10 collect (random [0,0,0] [100,100,0])

indexArray = for i = 1 to positions.count collect i

qsort indexArray compareFN valArray:positions

for i = 1 to positions.count do print positions[indexArray[i]]

amin ( <array> | {value} )

Returns minimum value of items in the array or of the argument values. If the array size is zero or no arguments are specified, the value undefined is returned. Examples:

myMin1 = amin #(5,1,4,2,8)

myMin2 = amin 5 1 4 2 8

amax ( <array> | {value} )

Returns maximum value of items in the array or of the argument values. If the array size is zero or no arguments are specified, the value undefined is returned.

Note: As described in Reference Assignment, the elements in an array are stored by reference rather than by value. When you operate directly on array elements, and the reference to the array is stored in more than one place, unexpected results may occur. An example of this is shown in the following script.

Script

RandomSets=#() -- create array

RandomSet=#()                 -- create array

for i=1 to 3 do               -- loop i

( for j=1 to 3 do             -- for each i loop j

RandomSet[j]=random 1 100 -- set array element to random value

print RandomSet #nomap -- print array of random values

RandomSets[i]=RandomSet -- store random value array in array

)

print RandomSets              -- print array of arrays of random values

Output

#() -- result of line 1

#()                           -- result of line 2

#(33, 47, 31)                 -- output from line 6, i=1

#(4, 52, 39)                  -- output from line 6, i=2

#(52, 36, 23)                 -- output from line 6, i=3

OK                            -- result of for loop, lines 3 to 8

#(52, 36, 23)                 -- 3 lines of output from line 7

#(52, 36, 23)

#(52, 36, 23)

OK                            -- result of line 9

As can be seen in the output lines 7 to 9, all the elements of array RandomSets contain the same values, which is not the result as expected from the output shown on lines 3 to 5. The reason the same values are stored in each element of RandomSets is only one array value is actually ever created for RandomSet (in line 2), and line 5 of the script is only changing the elements of that array value. Thus each element of RandomSets is actually pointing at the exact same value. The easiest fix for the above script is to move line 2 into the for i loop expression, thereby creating a new array value which will then be stored in RandomSets.

Script

RandomSets=#()

for i=1 to 3 do

(  RandomSet=#()                -- create a new array value for RandomSet

for j=1 to 3 do

RandomSet[j]=random 1 100

print RandomSet #nomap

RandomSets[i]=RandomSet

)

print RandomSets

Output

#()

#(89, 27, 88)

#(87, 87, 10)

#(74, 27, 64)

OK

#(89, 27, 88)

#(87, 87, 10)

#(74, 27, 64)

OK

You can convert object sets and wild-card pathnames to arrays using the as operator. This has the effect of taking a "snapshot" into the array of the current objects in the set or those matched by the pathname, so that you can then later work on that collection of objects without worrying if the set or match has changed. This is similar to named selection sets in the 3ds max user interface, and can be used, for example, to keep track of selections as you work interactively with MAXScript. If the user deletes from the scene any of the objects in the array, you will get an error if you try to map operations over the array.

Examples

sel1 = selection as array

boxes_at_load = $box* as array

snap_children = $torso...* as array

original_cameras = cameras as array