How to sort a string array by numeric value?

How to sort a string array by numeric value?

malcolm_341
Collaborator Collaborator
1,475 Views
13 Replies
Message 1 of 14

How to sort a string array by numeric value?

malcolm_341
Collaborator
Collaborator

Is it possible to sort a string array numerically?

I have this

string $array[] = {"3", "1", "9" "22", "2"};

 

and I want this

{"1", "2", "3" "9", "22"};

0 Likes
Accepted solutions (1)
1,476 Views
13 Replies
Replies (13)
Message 2 of 14

mcw0
Advisor
Advisor

Convert your numerical string array to an integer array.  Then sort.  Now loop through the sorted values and convert back to string to get the indices to sort your original numerical string array.

0 Likes
Message 3 of 14

malcolm_341
Collaborator
Collaborator

That won't work unfortunately, part of the string array is names so if I convert to int the names are lost. I'd like to sort this list

{"8=geo32", "6=geo26", "3=geo87", "22=geo11", "1=geo3", "2=geo7"}

and get this

{"1=geo3", "2=geo7", "3=geo87", "6=geo26", "8=geo32", "22=geo11"}

0 Likes
Message 4 of 14

mcw0
Advisor
Advisor

Tokenize with the "=", then you have only numbers as the first token

0 Likes
Message 5 of 14

malcolm_341
Collaborator
Collaborator

Yep, exactly, I tried that for 3 days, but couldn't figure out how to then stitch the sorted number list back onto the object names in the right order.

0 Likes
Message 6 of 14

osidedan
Advocate
Advocate

You could do it with tuples in a sorted list in Python, but if you need it to be MEL I'm not sure how to do that. Here's the python version though just in case, might spark some ideas!

list_raw = ['8=geo32', '6=geo26', '3=geo87', '22=geo11', '1=geo3', '2=geo7']
list_as_tuples = []
for item in list_raw:
    split = item.split('=')
    list_as_tuples.append((int(split[0]),'=' + split[1]))

list_as_tuples.sort()
print (list_as_tuples)

list_stitched = []
for item in list_as_tuples:
    list_stitched.append(str(item[0]) + item[1])

print (list_stitched)

 

print output:[(1, '=geo3'), (2, '=geo7'), (3, '=geo87'), (6, '=geo26'), (8, '=geo32'), (22, '=geo11')]
['1=geo3', '2=geo7', '3=geo87', '6=geo26', '8=geo32', '22=geo11']

0 Likes
Message 7 of 14

malcolm_341
Collaborator
Collaborator

Thanks for the suggestion, but I need it to be mel to work in Maya LT.

0 Likes
Message 8 of 14

osidedan
Advocate
Advocate

oh wow, I had no idea that Maya LT was THAT limited. Just about every other "indie" version of pro 3d software out there still has Python scripting abilities. I mean, even the free versions of other 3D apps still have Python.  Seems like a terrible call by autodesk to limit something as simple as Python scripting.

well, either way, I wish you luck on your quest to solve your problem!

Message 9 of 14

AssassinKKD
Participant
Participant

string $array[] = {"8=geo32", "6=geo26", "3=geo87", "22=geo11", "1=geo3", "2=geo7"};
print(sort($array));

this prints

1=geo3
22=geo11
2=geo7
3=geo87
6=geo26
8=geo32

 

I think the sort function in mel only counts the first index of a string, sorry I don't have much knowledge in mel

0 Likes
Message 10 of 14

malcolm_341
Collaborator
Collaborator

Yes correct, as discussed above sort doesn's work on string numbers it only works on float numbers.

0 Likes
Message 11 of 14

tkaap2
Autodesk
Autodesk
Accepted solution

MEL is a product of the time it was invented, so there are some extra steps to break down strings and reassemble them.  This procedure will sort your array.  The steps are what others here have described -- break each array element into an integer part and a string part, sort the integers, then reassemble the string parts back onto the integer parts, using the newly-sorted ordering.  Hopefully this helps!

global proc string[] sortIntStringArray(string $inputArray[])
{    
	print("The input array is:\n");
	print($inputArray);
	print("\n");

	string $buffer[];
	int $arraySize = size($inputArray);

	// split the input array into a list of numbers.  Store the string
	// payloads off to the size until later.
	int $indexArray[];
	string $stringBufferArray[]; // holds the string payloads from the input
	int $numTokens = 0;
	int $i;
	int $integerFromString;
	for($i=0; $i < $arraySize; $i++)
	{
		// split each input element into the part before '=' and the part after it.
		tokenize $inputArray[$i] "=" $buffer; 
		// convert the string representation of the integer into an actual integer.
		$integerFromString = int($buffer[0]);
		// append the integer to an integer array.
		$indexArray[$i] = $integerFromString;

		// add the string payload to a string array, but use the integer portion as 
		// the index into this (sparse) array so that we can retrieve it easily later.
		$stringBufferArray[$integerFromString] = $buffer[1];
	}

	// Sort the list of just integer indices.  If all you need is the sorted list of integers, 
	// use this.
	$indexArray=sort($indexArray);
	print("Found these indices:\n");
	print($indexArray);
	print("\n");

	string $stringArray[];
	//Now rebuild the string array using the sorted indices from $indexArray. 
	for ($i=0; $i < size($indexArray); $i++){
		$stringArray[$i] = ($indexArray[$i] + "=" + $stringBufferArray[$indexArray[$i]]);
	}

	// $stringArray is now the sorted-by-integer result of the input
	print("The sorted array is now:\n");
	print($stringArray);
	print("\n");

	// Return this array for other use.
	return $stringArray;
}

{
	// Call the sorting function with the example input array:
	string $array[] = {"8=geo32", "6=geo26", "3=geo87", "22=geo11", "1=geo3", "2=geo7"};
	$array = sortIntStringArray($array);
	print("The returned array is now:\n");
	print($array);
	print("\n");
}



The input array is:
8=geo32
6=geo26
3=geo87
22=geo11
1=geo3
2=geo7

Found these indices:
1
2
3
6
8
22

The sorted array is now:
1=geo3
2=geo7
3=geo87
6=geo26
8=geo32
22=geo11

The returned array is now:
1=geo3
2=geo7
3=geo87
6=geo26
8=geo32
22=geo11

 

Message 12 of 14

malcolm_341
Collaborator
Collaborator

Wow that's great thanks, I had already had the first part working tokenizing and stitching, but I couldn't figure out how to stitch them back in the right order after they were sorted.

0 Likes
Message 13 of 14

mcw0
Advisor
Advisor

I thought this was already sorted (pun intended).  If I knew you were still having trouble with the code, I would have provided it.  Sorry about that.

0 Likes
Message 14 of 14

malcolm_341
Collaborator
Collaborator

I solved my specific issue by ignoring names altogether and sorting by world space distance, but I still wanted to know how to do this for future scripts it's a handy technique.

0 Likes