Notifications
Clear all

[Closed] Sort multidimentional array

Hi,
While looking in the forum I have found this very interesting post :

Sorting Multidimensional Arrays
Hello everyone!

I need some help with Maxscript, the situation is the following:

I have a multidimensional array which has strings, integers, booleans and so on in different sub-arrays.

For example:
multidim = #(#(“John”,“Paul”,“Sam”,“Andy”),#(1,2,3,4),#(true,true,false,false)

I would like to sort the multidimensional array by names keeping the original structure. In this case I would like see the following:

multidim = #(#(“Andy”,“John”,“Paul”,“Sam”),#(4,1,2,3),#(false,true,true,false)

I would really appreciate any help, thank you!


Hi,

You could create an index array based on the 1st array sort something like:

Code:

MyArray= #(#(“John”,“Paul”,“Sam”,“Andy”),#(1,2,3,4),#(true,true,false,false))
– Make a copy of the ‘Names’ array
tmpArray=Deepcopy MyArray[1]
sort tmpArray
– Create the sorted Index array
SortedIndexArray = for i in tmpArray collect (findItem MyArray[1] i)
– Copy the original array
tmpArray=Deepcopy MyArray
– re-order the elements of the copy accordin g to the original
for j=1 to MyArray.count do
(
for i =1 to SortedIndexArray.count do
tmpArray[j][i]=MyArray[j][SortedIndexArray[i]]
)
– copy the sorted array back to original
MyArray=tmpArray

This is GREAT but, in my case I will have MyArray= #(#(“John”,“John”,“Sam”,“Andy”),#(1,2,3,4))
whish of course breaking the next line : SortedIndexArray = for i in tmpArray collect (findItem MyArray[1] i) giving me two times the same index for Jhon.
Anyone could help me to figure out how to turn around this ?

Thanks
Blobynator.

4 Replies

there are ways to do this task via mxs.

pure mxs

mxs with dotnet help

the thing calls linked sort.

#1 will work well and fast enough if you have unique sorting sub-arrays (all items unique)

make a copy of sorting array (the first in your case)

sort the array

loop through sorted array with finditem finding item’s index in the array before sorting

reorder (collect in new order) other sub-arrays using this mapping (new indexes to old)

#2 is shown in one of my posts… can’t find it… well
the idea is:

convert mxs array to dotnet array (sorting array)

make new dotnet array using indexes from 1 to number of sorting items (linked array)

sort ‘sorting’ array with ‘linked’

convert ‘sorting’ array to mxs array

use ‘linked’ array to reorder (recollect) other sub-array

Thanks Denis,

The first solution you gave is what I have done if I am not wrong ? So since all my items are not different it don’t work :hmm:
I have not try using dotnet but instead I have end up using a qsort function which made me lose quite some hairs… but after have fight bravely I have finally succeed and conquest the Sorting of my arrays.

Thanks !


   fn comparefn i j values: =
   (	
   	v1 = values[i]; 
   	v2 = values[j];
   	if v1 < v2 then 1 else if v1 > v2 then -1 else 0;
   )	
   
   
   MyArray = #(#("John","Paul","Sam","Andy"),#(1,2,3,4),#(true,true,false,false));	
   indexes = #{1..MyArray[1].count} as array;	
   
 -- sort the indexes array based on the values in the array of names
   qsort indexes comparefn values:MyArray[1];
 -- use the sorted indexes to "index" into each sub array
   for i = 1 to indexes.count do
   	format "% % %
" MyArray[1][indexes[i]] MyArray[2][indexes[i]]  MyArray[3][indexes[i]];
   

or not in reverse order


  fn comparefn i j values: =
  (	
  	v1 = values[i]; 
  	v2 = values[j];
  	if v1 > v2 then 1 else if v1 < v2 then -1 else 0;
  )	
  
  
  MyArray = #(#("John","Paul","Sam","Andy"),#(1,2,3,4),#(true,true,false,false));	
  indexes = #{1..MyArray[1].count} as array;	
  
  qsort indexes comparefn values:MyArray[1];
  
  for i = 1 to indexes.count do
  	format "% % %
" MyArray[1][indexes[i]] MyArray[2][indexes[i]]  MyArray[3][indexes[i]];
    

sorry if it’s a bit vague but I am so drunk at the moment * love sunny sundays peace