As 3dsmax doesn't allow for either associative arrays or dynamically-set object properties, it can be difficult to store unstructured, arbitrary variables.
Sometimes you just want to store lists of name/value pairs, to keep track of a few settings throughout your script, without relying on a host of variables, resorting to .ini files, or custom attributes.
Therefore, I set about writing a basic Dictionary, or List struct, similar to VB and other languages.
Example code
Here's a really basic example of storing 5 named variables within a List:
names = #("five", "four", "three", "two", "one") values = #(5,4,3,2,1) lst = List() for i = 1 to 5 do lst.addItem names[i] values[i]
So let's get some data back out:
lst.getValue "two" -- 2 lst.getIndex "two" -- 4 lst.getValues() -- #(5, 4, 3, 2, 1)
Or print the whole lot:
lst.print() -- unsorted five: 5 four: 4 three: 3 two: 2 one: 1
How about some sorting:
lst.sort() -- by name, alphabetically five: 5 four: 4 one: 1 three: 3 two: 2 lst.sort field:#value -- by value one: 1 two: 2 three: 3 four: 4 five: 5
As you can see, it's pretty straightforward stuff!
Properties and Methods
Properties
- <array> items <name> <value> – the key/value pairs.
- Names can be a #name, "string", or even an index
- Values can be any MaxWrapper value (i.e. anything)
Setters
- <ListItem> addItem <name> <value> – adds an item to the List, and if it already exists
- <ListItem> setItem <name> <value> – synonym for the above
Getters
- <value> getValue <name> – returns the value of the named item
- <index> getIndex <name> – returns the index of the named item
- <name> getName <value> – returns the name of the first item that matches the supplied value
- <ListItem> getItem <name> – returns the List item corresponding to the supplied name (typically, you wouldn't use this, as you know the name component already, it's just included for completeness)
- <array> getItems() – returns all items as an array of ListItem structs
- <array> getNames() – returns all names as an array
- <array> getValues() – returns all values as an array
Clear or delete
- <array> clear() – clears the lit of all items, and returns the empty ListItems array
- <boolean> deleteItem <name> – deletes the named item from the list, and returns it
- <boolean> deleteIndex <index> – deletes the item at the index, and returns it
Utilities
- <array> sort field:<name> order:<name> func:<function> – sorts the list in a variety of ways, even supply a comparison function (see the max help on qsort)
- <string> print() – prints the List items to the Listener
Next version
Possible improvements in the next version might be:
- .ini file integration, with save() and load() methods
- Support for hierarchical Lists, perhaps getValue #(#parent, #child, #grandchild, …)
Download
Download List.struct.ms here.
Hey Dave,
Thanks for saving me a lot of time. I was thinking of a better way to organise my struct-arrays, and this is exactly what I was looking for. I'll add a new comment whenever I get time to test it a little better.
diffx