Sort multidimentional array

Become a member of the CGSociety

Connect, Share, and Learn with our Large Growing CG Art Community. It's Free!

 
Thread Tools Search this Thread Display Modes
Old 04 April 2014   #1
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.

Last edited by Blobynator : 04 April 2014 at 12:45 PM.
 
Old 04 April 2014   #2
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
 
Old 04 April 2014   #3
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
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 !
 
Old 04 April 2014   #4

   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 "% % %\n" MyArray[1][indexes[i]] MyArray[2][indexes[i]]  MyArray[3][indexes[i]];
   

Last edited by Klvnk : 04 April 2014 at 05:43 PM.
 
Old 04 April 2014   #5
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 "% % %\n" 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

Last edited by Klvnk : 04 April 2014 at 05:49 PM.
 
reply share thread



Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

vB code is On
Smilies are On
[IMG] code is On
HTML code is Off
CGSociety
Society of Digital Artists
www.cgsociety.org

Powered by vBulletin
Copyright 2000 - 2006,
Jelsoft Enterprises Ltd.
Minimize Ads
Forum Jump
Miscellaneous

All times are GMT. The time now is 10:40 PM.


Powered by vBulletin
Copyright ©2000 - 2017, Jelsoft Enterprises Ltd.