MaxScript: can I sort an array based on another array?

max
maxscript

#1

I have an object array, and I also have a material name array which is corresponding with the object array. Example: The object at index 9 have the material names at index 9 in the material name array.

I want to sort the material name array based on the count, which I can do with a normal qsort. But I also want the same sorting applied to the object array, so I keep the corresponding index number.
How can I do this? Is it possible to sort multiple arrays in a single qsort?


#2

Does it have to be MaxScript? There are easy ways to accomplish what you want by hopping over to .Net classes or Python.


#3

Jeff,
I do not know anything about .Net classes.
I prefer to solve it in maxScript, but that is mostly since I haven´t taken a dive into Python for 3dsmax yet. I have planned to do it though :slight_smile:

Say there is no way to fix this in maxScript and I choose to do it in Python. Can I write a simple class in Python and run it at a specific time in maxscipt? Just like a simple import or something …


#4

python.import will import a module and then you can access any attribute from said module like a normal maxscript function.
I would strongly recommend doing it in python if you can though. Python will likely not only be much easier to solve but much more performant too.
If you are dead set on maxscript and are wanting to do what I think you are, then you have to record the sorted and unsorted indices of the source array and then build a new array from said indices of the array you wish to sort.
I would suggest starting with a simple two element array and see if you can get the logic to work.
Something like this:

-- define your arrays:
array1 = #("b", "a")
array2 = #("B", "A")
-- sort array1, by default this will be alphabetical:
array1Sorted = Sort array1
-- define a new array to insert the sorted items into:
array2Sorted = #()
array2Sorted[array1.count] = Undefined
for a = array1.count do
(
    local sortedIndex = ( findItem array1Sorted array1[a] )
    array2Sorted[sortedIndex] = array2[a]
)

print(array1Sorted)
print(array2Sorted)

#5

Munkybutt,
Your solution is nice. I thought it wouldn´t work for my situation, but as I wrote I realised it will work anyway :P.

In regard to findItem:
Does maxScript treat an array (or sub-array) as unique, even if its items are identical with another array?
If I copy an array with sub-arrays, then sort the copy, then use findItem to find the new index number, will it find that exact sub-array, or will it find the first sub-array with identical items?

I also want to run two qsorts in my code. The first will sort based on object face count, while the next will sort based on material count. The second qsort is most important, but it will return a lot of equal results since many objects will contain the same number of materials.
Will the second qsort keep the original sorting as intact as possible in the cases where it returns an equal results, or will equal results be randomized?


#6

Each array is a unique object and therefore will not match another array, even with the same elements in the same order. Enter this in your listener and you will see that it returns False:

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

You can convert the arrays to a strings and compare them:

( #(1, 2, 3) as String ) == ( #(1, 2, 3) as String )

or compare each element of the sub array:

array1 = #(1, 2, 3)
array2 = #(1, 2, 3)
itemsMatch = True
for a = 1 to array1.count while itemsMatch do
(
    if array1[a] != array2[a] do
    (
        itemsMatch = False
    )
)
itemsMatch

Both of which will return True and both will be exceptionally slow to do, especially if you have a large array.

The example I have given will require unique array elements as findItem returns the first index matching the given argument, which you can test with the following code:

array1 = #(1, 1, 1)
findItem array1 1

You could add an extra element to each sub - array as a unique ID:

uniqueArrays = for a = 1 to 10 collect #( 1, 2, a )

Will contain 10 arrays, whereby the first two elements are your data and the third elements is the unique ID.
So all arrays are technically unique, yet they contain the same identical data in the first two elements.

Honestly, as I said above, you would be much better off solving this problem in Python, it will be much easier and much more performant. Here is a post on the very subject:


#7

Thanks Munkybutt, very helpful :slight_smile:

I see that Python obviously has better ways to handle my problem. I will seriously consider it.