Link to home
Start Free TrialLog in
Avatar of OggieOne
OggieOne

asked on

Sorting ArrayList Objects.

Hi all, this question has been asked before but I am not sure a working example was ever posted. The below code example works when using the first string array and bombs using the second string array. Can anyone please help?
Thanks!
import java.util.*;
 
public class SortObjects
{     
     public static void main(String s[])
     { //The first string works and the second one bombs. The difference is the 5th element
		//String t[] = { "1", "19", "2", "3pt1", "4", "5pt1", "6pt2", "7pt3", "7pt3" };
		String t[] = { "1", "19", "2", "3pt1", "3", "5pt1", "6pt2", "7pt3", "7pt3" };
						
 
        // The input is a String array. Make that an ArrayList:
        List inputList = new ArrayList(Arrays.asList(t));          // replace "t" by "s" for using the command line arguments
        
        List l = sort(inputList);
          
        System.out.println("\nStrings sorted List ...");
        for(int i = 0; i < l.size(); i++) 
            System.out.println((String)l.get(i)); 
    }
     
    public static List sort(List list) {
          Collections.sort(list, new Comparator() {
 
            public int compare(Object o1, Object o2) {
                 String s1 = (String)o1;
                 String s2 = (String)o2;
 
                 String integer1[] = s1.split("[^0-9]");      // <<<<<  changed
                 String integer2[] = s2.split("[^0-9]");      // <<<<<  changed
                 String chars1[] = s1.split("[0-9]+");         // <<<<<  changed
                 String chars2[] = s2.split("[0-9]+");         // <<<<<  changed
 
                 Integer i1 = new Integer( Integer.parseInt(integer1[0]) );
                 Integer i2 = new Integer( Integer.parseInt(integer2[0]) );
 
                 if (i1.equals(i2))
                    return chars1[1].compareTo(chars2[1]);
                  else
                     return i1.compareTo(i2);
            }
        });
        return list; 
    }
}

Open in new window

Avatar of Kevin Cross
Kevin Cross
Flag of United States of America image

Think it is bombing because 3 equals 3 from 3pt1 then you are dropping into this code:
return chars1[1].compareTo(chars2[1]);

For 3, there is no chars2[1].  It works with other string as there are no values that satisfy condition 1 where values equal and the values aren't the exact same string.

As a question, why are you not just comparing these as strings?  If you use:

List<String> list = new ArrayList<String>(Arrays.asList(t));

This should sort without need of a special comparator object as Strings can be compared already.
Avatar of OggieOne
OggieOne

ASKER

I can't compare everything as strings as the data that I need to sort are combinations of numbers and letters. For example I need to sort 1 , 2 , 3 , 3pt1 , 3pt2 , 4 , 4pt1 , 5pt .... etc..Make sense?

Thanks.
Sorry..I should add this. Once you get to say 10pt2 the order then becomes

1, 10pt2, 2, 3, 4 etc...when 10pt2 should be at the bottom of the list and not after 1.
Makes sense.  Did you see my comment on what you should look at in code.  The string comparison was just a side suggestion, I did give an answer to your question above too.

Let me know what issues you are having after looking into that.

Regards,
Kevin
Yes I did see where it bombs. I guess my real question would be then how do I fix that? Do I need to start testing the length and if it's not there return --> return chars1[1]
I guess this whole sorting thing is a bit beyond my comprehension.
Thanks for your help.
It seems to work now and I get the same sorted results regardless of wether I return a 0 or a -1 when there is no chars2[1]. For example this *appears* to sort correctly now.

              if (i1.equals(i2)){
                    try{
                        return chars1[1].compareTo(chars2[1]);
                    }
                    catch(Exception e){
        return 0;
                    }
              }
              else{
                    return i1.compareTo(i2);
              }
                    
Help! It still doesn't work..even though I said it did. Now if you pass a string that doesn't start with a number it throws a NumberFormatException even though I see the above if statement return a 0. Any ideas?

By adding the following to the string array -> pt2

Thanks!
You  can take this approach to get the exact (i guess) result you need:

http://technojeeves.com/joomla/index.php/free/64-java-custom-comparator-with-generics
Thanks for the post! Perhaps I should eloborate on what I am doing. The values for the string come from a database that has no restriction on what they can enter. This case is actually movie/tv scenes.
So users can enter Scene 1ptA or 1pt2 or A1 or whatever they want (usually guided by a movie script).
I see your sample has the hardcoded "pt" but sadly I won't know what the actual letters are. The sort that I have only blows up when the scene doesn't start with a number. I currently *hacked* it to pre-pend a ZERO if it doesn't start with a number but that is a bit of a hack...ok maybe more than a bit :-)

Is there a better way to do this?

Thanks,
Doug
The best way is to constrain input, otherwise you have a 'garbage in, garbage out' scenario. There's no such thing as code that can cope with arbitrary input
That is because the whole code above is based on values starting with a number:

Integer i1 = new Integer( Integer.parseInt(integer1[0]) );

This indicates that there will always be an integer to parse at index 0 of the array.

If you can't constrain the data, I would suggest you make this much simplier and check if the entire number is numeric and then sort as number otherwise sort as text and just decide which come first text or numbers.  You can probably go through to sort the text and numbers together as you are so that 10 and 10pt1 sort together; however, you will have to account for every single variation of the string the database can throw out.

For example what is stopping the db from sending pt10-12 and how would that sort with pt10-9.

Anyway, don't want to belabour this.
I wish I could constrain the input better but I think I can only recommend a certain format for best sorting results.
Thanks for all your help.
Doug
Is it a web form?
Understand and you are welcome.

Like I said, you seem comfortable with regular expressions, I would just check if the string is all numbers and then convert to integer and compare otherwise compare as string.  You can also return appropriate greater than or less than response based on how you want integers to sort with respect to text.

-1 means smaller
0 means equal
1 means greater
Yes the data is submitted via a webpage (form). I just can't restrict the users of my application as to what they say a movie scene number may be called. I have to let them say what it is (ie: mix of numbers and letters).
So the problem arises when the user enters a combination of letters and numbers, therefore I can't sort as a string or as a number.
I think the *hack* I have in place will have to do and I then recommend to the users that a scene should start with a number and NOT a letter.

Thanks,
Doug
Using a drop down of scene numbers would do it would it not?
Nope, can't do that. All productions are different.....sadly.
I would agree with CEHJ on getting control of the source, but if you cannot here is an example of what I meant by sorting the text and numbers separately.

http://crossedlogic.blogspot.com/2008/11/java-custom-comparators-sorting-text.html

You can modify this to your liking as the implementation sorts numbers first, then text with numbers in front, then text (possibly withn numbers after first character(s)).  The code for the middle case may be used to sort everything intermingled as you desired ...
public static java.util.List<String> sort(java.util.List<String> list) {
		java.util.Collections.sort(list, new java.util.Comparator<String>() {
			/**
			 * Custom compare to sort numbers as numbers. Strings as strings,
			 * with numbers ordered before strings.
			 * 
			 * @param o1
			 * @param o2
			 * @return
			 */
			@Override
			public int compare(String o1, String o2) {
				boolean isFirstNumeric, isSecondNumeric;
 
				isFirstNumeric = o1.split("[^0-9]")[0].matches("\\d+");
				isSecondNumeric = o2.split("[^0-9]")[0].matches("\\d+");
 
				if (isFirstNumeric) {
					if (isSecondNumeric) {
						int intCompare = Integer.valueOf(o1.split("[^0-9]")[0])
								.compareTo(
										Integer.valueOf(o2.split("[^0-9]")[0]));
						if (intCompare == 0) {
							return o1.compareToIgnoreCase(o2);
						}
						return intCompare;
					} else {
						return -1; // numbers always smaller than letters
					}
				} else {
					if (isSecondNumeric) {
						return 1; // numbers always smaller than letters
					} else {
						return o1.compareToIgnoreCase(o2);
					}
				}
			}
 
		});
		return list;
	}

Open in new window

Thanks! I will try that first thing tomorrow! Your help is greatly appreciated (everyones).
OK here goes my first stupid question for the day..(how many am I allowed?)...
Here are my results from using the above sort.
7pt1
7pt10
7pt10
7pt12
7pt14
7pt4
7pt4
7pt5
7pt5
7pt5
7pt6
7pt6
7pt6
7pt7
7pt7
7pt8
7pt8

Can the sort be modified to sort the following so that they appear AFTER the 7pt8?

7pt10, 7pt10, 7pt12, 7pt14

The 7pt10 etc...should NOT be before 7pt4.

Is this possible?

Thanks Again!

You obviously didn't run the code i posted ;-)
It is possible, you are just asking for extra headaches as you don't have a standard format, so you will have to continual keep checking if a part is numeric.  I would just stop at the top level personally.

But you should be able to adjust the logic from what I gave you.

CEHJ, the point I think is that 'pt' is not necessarily part of the string.  Think that was just an example.
>>CEHJ, the point I think is that 'pt' is not necessarily part of the string.

I'm aware of that - yet it's come back and is being used again for some reason ;-)
CEHJ - which code are you referring to? The one with the hard coded "pt" in it?

And yes it is like I am begging for headaches. Sadly I have no choice and cannot stop people from entering whatever they want. This code is for television and movie scripts and people can call a scene all sorts of wonderful things. So it could end up Scene -> 7part1 or 7pt1 or 7ptA or 7pt1A.
As for "adjust the logic "..since I don't understand fully what you did I am not sure I am capable of adjusting the code...again sadly. Although that code woudn't comile as is. I got this error ->

The type new Comparator(){} must implement the inherited abstract method Comparator.compare(Object, Object)

So I added the method.
Thoughts?


>>CEHJ - which code are you referring to? The one with the hard coded "pt" in it?

Yes, IOW the one that will work correctly with the example input you just posted
Yes you are correct CEHJ, I didn't run that code as the hard coded "pt" doesn't always apply it just happens to be what one of my users is entering.
Perhaps though I can use that and remove whatever the characters are before sorting.
>>I didn't run that code as the hard coded "pt" doesn't always apply it just happens to be what one of my users is entering.

Yes i know that it doesn't always apply, yet you *are* running it with the other code, that i didn't supply ...

>>Perhaps though I can use that and remove whatever the characters are before sorting.


Yes, for the middle, you can use the pattern "\D+" instead of "pt"
Sorry

"\\D+"
OK I just tried that and I still get the following results.

sceneNumber = 7pt1
sceneNumber = 7pt10
sceneNumber = 7pt10
sceneNumber = 7pt12
sceneNumber = 7pt14
sceneNumber = 7pt4
sceneNumber = 7pt4
sceneNumber = 7pt5
sceneNumber = 7pt5
sceneNumber = 7pt5
sceneNumber = 7pt6
sceneNumber = 7pt6
sceneNumber = 7pt6
sceneNumber = 7pt7
sceneNumber = 7pt7
sceneNumber = 7pt8
sceneNumber = 7pt8

The code I ran is included and is from CEHJ (I switched the "pt" with the "\\D+"

Thanks,
Doug

	public static void sort(List list) 
	{        
		Collections.sort(list, new Comparator() {
				
			public int compare(Object o1, Object o2) {
				return compare( o1.toString() , o2.toString() );
			}			
 
			
			public int compare(String s1, String s2) {
				int result = 0;
				double val1;
				double val2;
				String[] temp1 = s1.split("\\D+");
				String[] temp2 = s2.split("\\D+");
				if (temp1.length > 1) {
					val1 = Double.parseDouble(
							new StringBuilder().append(temp1[0]).append('.').append(temp1[1]).toString());
				}
				else {
					val1 = Double.parseDouble(s1);
				}
				if (temp2.length > 1) {
					val2 = Double.parseDouble(new StringBuilder().append(temp2[0]).append('.').append(temp2[1]).toString());
				}
				else {
					val2 = Double.parseDouble(s2);
				}
				if (val1 > val2) {
					result = 1;
				}
				else if (val2 > val1) {
					result = -1;
				}
				else {
					result = 0;
				}
				return result;
				}
			}
		);}

Open in new window

Yes, but that's *not* the code i wrote. Mine uses generics and does not have the method

compare(Object ....
I couldn't compile the code as supplied as I stated earlier. What was I supposed to do then?
I don't understand what you mean by "Mine uses generics". How would I implement that then?
I merely added the the method that it was complaining about.
CEHJ, he used your code with an additional compare method in it is all. ;)

BTW, if you split on "\\D+" instead of "pt" then you are splitting on the numbers instead of on the string as you were previously.  Think you want "[^\\D]+" or "[^0-9]+".  Maybe uppercase D means something different than lowercase d.
Use my code here http:#22936164 as a base which you got to compile and then just swap in CEHJ's implementation of sort().
new java.util.Comparator<String> <-- the <String> part is using generic.  Comparator with <?> is raw type.
...meant Comparator *without* <?> is raw type by the way.
It's almost identical, but the differences will break it entirely. See below:
        public static void sort(List list) 
        {        
                Collections.sort(list, new Comparator<String>() {
                        
                        public int compare(String s1, String s2) {
                                int result = 0;
                                double val1;
                                double val2;
                                String[] temp1 = s1.split("\\D+");
                                String[] temp2 = s2.split("\\D+");
                                if (temp1.length > 1) {
                                        val1 = Double.parseDouble(
                                                        new StringBuilder().append(temp1[0]).append('.').append(temp1[1]).toString());
                                }
                                else {
                                        val1 = Double.parseDouble(s1);
                                }
                                if (temp2.length > 1) {
                                        val2 = Double.parseDouble(new StringBuilder().append(temp2[0]).append('.').append(temp2[1]).toString());
                                }
                                else {
                                        val2 = Double.parseDouble(s2);
                                }
                                if (val1 > val2) {
                                        result = 1;
                                }
                                else if (val2 > val1) {
                                        result = -1;
                                }
                                else {
                                        result = 0;
                                }
                                return result;
                                }
                        }
                );}

Open in new window

I am in over my head here as I do not know how I can get this to compile.
Collections.sort(list, new Comparator<String>()......

In both of your (CEHJ and mwvisa1) code examples you reference <String> and I cannot compile a class with that sort of declaration in it. What am I missing here?

Thanks,
Doug


Sorry - for some reason i thought you were using >= 1.5 What version are you using?
If you're using < 1.5, just begin

                Collections.sort(list, new Comparator() {
                        
                        public int compare(Object o1, Object o2) {
                                int result = 0;
                                double val1;
                                double val2;
                                String s1 = (String)o1;
                                String s2 = (String)o2;
                                String[] temp1 = s1.split("\\D+");
                                String[] temp2 = s2.split("\\D+");

Open in new window

OK I am getting somewhere at least after switching JDK's. Here is the exact code that I am running (it is your code CEHJ). And the output is still not ordered as *we* expect.
sceneNumber = 7pt1
sceneNumber = 7pt10
sceneNumber = 7pt11
sceneNumber = 7pt12
sceneNumber = 7pt2
sceneNumber = 7pt3
sceneNumber = 7pt3
sceneNumber = 7pt5
sceneNumber = 7pt5
sceneNumber = 7pt6

Thoughts?
Thanks,
Doug

import java.util.Collections;
import java.util.Comparator;
import java.util.List;
 
public class Sort3 {
	
	public static void main(String[] args){
		Sort3 sorter = new Sort3();
		try{
			sorter.run();
		}
		catch(Exception e){
			System.out.println("Error : " + e.toString() );
		}
	}
	
	private void run() throws Exception
	{
	    
	    String[] inputStringArray = { "7pt1", "7pt2", "7pt3", "7pt3", "7pt5", "7pt6", "7pt10", "7pt11", "7pt12", "7pt5" };
	    java.util.List<String> inputList = new java.util.ArrayList<String>(java.util.Arrays.asList(inputStringArray));	    
	    sort( inputList );
	    for ( int i = 0 ; i < inputList.size() ; i++ ){
	    	String sceneNumber = ( String ) inputList.get( i ) ;
	    	System.out.println("sceneNumber = " + sceneNumber );
	    }
	}
	
 
    public static void sort(List list) 
    {        
            Collections.sort(list, new Comparator<String>() {
                    
                    public int compare(String s1, String s2) {
                            int result = 0;
                            double val1;
                            double val2;
                            String[] temp1 = s1.split("\\D+");
                            String[] temp2 = s2.split("\\D+");
                            if (temp1.length > 1) {
                                    val1 = Double.parseDouble(
                                                    new StringBuilder().append(temp1[0]).append('.').append(temp1[1]).toString());
                            }
                            else {
                                    val1 = Double.parseDouble(s1);
                            }
                            if (temp2.length > 1) {
                                    val2 = Double.parseDouble(new StringBuilder().append(temp2[0]).append('.').append(temp2[1]).toString());
                            }
                            else {
                                    val2 = Double.parseDouble(s2);
                            }
                            if (val1 > val2) {
                                    result = 1;
                            }
                            else if (val2 > val1) {
                                    result = -1;
                            }
                            else {
                                    result = 0;
                            }
                            return result;
                            }
                    }
            );}
	
}

Open in new window

ASKER CERTIFIED SOLUTION
Avatar of CEHJ
CEHJ
Flag of United Kingdom of Great Britain and Northern Ireland image

Link to home
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Start Free Trial
Thanks for the code! I am trying to use it but I am at a loss as to how to invoke it? Sorry for my ignorance!
I was doing it like this before (see code snippet). How would I get my list into the new class?

Thanks!
Doug

OLD WAY...
    public static void sort(List list) 
    {        
     Collections.sort(list, new Comparator<String>() {
              public int compare(String s1, String s2) {
                            int result = 0;
etc.....

Open in new window

New way:
Collections.sort(list, new SceneComparer());

Open in new window

BRILLIANT!
Thank you soooo much!!

sceneNumber = 7pt1
sceneNumber = 7pt2
sceneNumber = 7pt3
sceneNumber = 7pt3
sceneNumber = 7pt5
sceneNumber = 7pt5
sceneNumber = 7pt6
sceneNumber = 7pt10
sceneNumber = 7pt11
sceneNumber = 7pt12
:-)
I spoke too soon.....now that I use my real data from the database I get the following error ( Error : java.lang.ArrayIndexOutOfBoundsException: 1 ).
Here is a listing of the data that gets passed to the sort. Any ideas? I wrapped single quotes around the value to make sure there were not any spaces.
See anything that would break it?

Thoughts?

Thanks!

myScenes[i] = '10'
myScenes[i] = '10'
myScenes[i] = '10'
myScenes[i] = '10Apt1'
myScenes[i] = '10Apt1'
myScenes[i] = '10Apt1'
myScenes[i] = '11'
myScenes[i] = '11'
myScenes[i] = '12'
myScenes[i] = '12'
myScenes[i] = '13'
myScenes[i] = '13'
myScenes[i] = '14'
myScenes[i] = '14'
myScenes[i] = '15pt1'
myScenes[i] = '15pt1'
myScenes[i] = '16'
myScenes[i] = '16'
myScenes[i] = '16'
myScenes[i] = '16'
myScenes[i] = '16'
myScenes[i] = '16'
myScenes[i] = '17'
myScenes[i] = '17'
myScenes[i] = '17'
myScenes[i] = '17'
myScenes[i] = '17'
myScenes[i] = '17'
myScenes[i] = '17'
myScenes[i] = '18'
myScenes[i] = '18'
myScenes[i] = '19'
myScenes[i] = '19'
myScenes[i] = '19'
myScenes[i] = '19'
myScenes[i] = '19'
myScenes[i] = '19'
myScenes[i] = '20pt1'
myScenes[i] = '20pt1'
myScenes[i] = '20pt1'
myScenes[i] = '20pt3'
myScenes[i] = '20pt3'
myScenes[i] = '21'
myScenes[i] = '21'
myScenes[i] = '21'
myScenes[i] = '22'
myScenes[i] = '23'
myScenes[i] = '24'
myScenes[i] = '24'
myScenes[i] = '24'
myScenes[i] = '24'
myScenes[i] = '25pt1'
myScenes[i] = '25pt1'
myScenes[i] = '25pt1'
myScenes[i] = '25pt1'
myScenes[i] = '25pt1'
myScenes[i] = '26'
myScenes[i] = '26'
myScenes[i] = '27pt1'
myScenes[i] = '27pt1'
myScenes[i] = '27pt1'
myScenes[i] = '29pt1'
myScenes[i] = '29pt1'
myScenes[i] = '29pt1'
myScenes[i] = '29pt2'
myScenes[i] = '29pt2'
myScenes[i] = '29pt2'
myScenes[i] = '29pt3'
myScenes[i] = '29pt3'
myScenes[i] = '29pt3'
myScenes[i] = '29pt4'
myScenes[i] = '29pt4'
myScenes[i] = '29pt4'
myScenes[i] = '29pt5'
myScenes[i] = '29pt5'
myScenes[i] = '29pt5'
myScenes[i] = '29pt6'
myScenes[i] = '2pt1'
myScenes[i] = '2pt1'
myScenes[i] = '2pt1'
myScenes[i] = '3'
myScenes[i] = '3'
myScenes[i] = '30pt1'
myScenes[i] = '31pt1'
myScenes[i] = '31pt1'
myScenes[i] = '31pt1'
myScenes[i] = '31pt1'
myScenes[i] = '31pt1'
myScenes[i] = '31pt1'
myScenes[i] = '31pt1'
myScenes[i] = '31pt2'
myScenes[i] = '31pt2'
myScenes[i] = '31pt3'
myScenes[i] = '32'
myScenes[i] = '32'
myScenes[i] = '32'
myScenes[i] = '32'
myScenes[i] = '33'
myScenes[i] = '33'
myScenes[i] = '34'
myScenes[i] = '34'
myScenes[i] = '35'
myScenes[i] = '35'
myScenes[i] = '35'
myScenes[i] = '36pt1'
myScenes[i] = '36pt1'
myScenes[i] = '36pt1'
myScenes[i] = '36pt1'
myScenes[i] = '36pt1'
myScenes[i] = '36pt1'
myScenes[i] = '36pt1'
myScenes[i] = '36pt1'
myScenes[i] = '36pt2'
myScenes[i] = '36pt3'
myScenes[i] = '36pt3'
myScenes[i] = '36pt3'
myScenes[i] = '36pt3'
myScenes[i] = '36pt3'
myScenes[i] = '36pt3'
myScenes[i] = '36pt3'
myScenes[i] = '36pt3'
myScenes[i] = '37pt1'
myScenes[i] = '37pt1'
myScenes[i] = '37pt1'
myScenes[i] = '37pt1'
myScenes[i] = '37pt1'
myScenes[i] = '37pt1'
myScenes[i] = '37pt2'
myScenes[i] = '37pt3'
myScenes[i] = '37pt3'
myScenes[i] = '37pt3'
myScenes[i] = '37pt3'
myScenes[i] = '37pt3'
myScenes[i] = '4pt1'
myScenes[i] = '4pt1'
myScenes[i] = '4pt1'
myScenes[i] = '5'
myScenes[i] = '5'
myScenes[i] = '5'
myScenes[i] = '6pt1'
myScenes[i] = '6pt1'
myScenes[i] = '7pt1'
myScenes[i] = '7pt10'
myScenes[i] = '7pt10'
myScenes[i] = '7pt12'
myScenes[i] = '7pt14'
myScenes[i] = '7pt4'
myScenes[i] = '7pt4'
myScenes[i] = '7pt5'
myScenes[i] = '7pt5'
myScenes[i] = '7pt5'
myScenes[i] = '7pt6'
myScenes[i] = '7pt6'
myScenes[i] = '7pt6'
myScenes[i] = '7pt7'
myScenes[i] = '7pt7'
myScenes[i] = '7pt8'
myScenes[i] = '7pt8'
myScenes[i] = '8pt1'
myScenes[i] = '8pt1'
myScenes[i] = '9'
myScenes[i] = '9'
myScenes[i] = '9'
myScenes[i] = '9'
Error : java.lang.ArrayIndexOutOfBoundsException: 1
Well the erroring value could be 'off screen'. Can you post the values as a text file attachment?
Those were all the values, but here it is in a txt file.
SceneValues.txt
SOLUTION
Link to home
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Start Free Trial
Sweet! It seems to work now from my actuall application! Thank you soooo much for your help I truly appreciate it.
The help I got was fantastic. A stubborn problem was finally solved. Thanks so much.
:-)
Argh! OK, is there a way you can tweak the sort to allow this kind of a data value?
38/40pt3

THANKS!!
Your situation is not supportable, as i mentioned earlier, since there's potentially an infinite number of tweaks that will need to be performed. I could be open to discussions of micropayment however if you contact me through my profile details
I will try to contact you through your profile but will post this here anyway.

I should clarify. The following doesn't sort and throws a NumberFormatException
'37pt3'
'38/40pt3'
'38/40pt6'
'41'
'45/46pt5'
'48'
'50pt1'
'51'
'61pt4'
'66'
'67pt2'
'68pt7'
'69pt2'
'70'
'71'
'72pt1'
'79pt1'
'79pt3'
'79pt5'

If I add for example scene '1' to this list the sort then works. Is it some of initialization error? So the 38/40pt3 does actually sort. Pretty weird. Thoughts?
Thanks!