- Home /
Sorting Game Object Name In Numerical and Alphabetical Order via List
I need help on this one. I took some research about sorting GameObject in alphabetical and numeric order. I implemented this code like this:
if(SortCardOrder) {
List<GameObject> cardOrder = null;
cardOrder = this.card[0].OrderBy(go=>go.name).ToList(); // --> I use this code to sort by name.
foreach(GameObject card in cardOrder) {
CardPosition[] position = card.GetComponents<CardPosition>();
// Display result here.
print ("[ CARD IN HAND ] --> " + position[0].getSuit() + " " + position[0].getCardNumber() +
" at player " + 1 + ".");
cardText.text += "" + position[0].getSuit() + " " + position[0].getCardNumber() +
" at player " + 1 + ". \n";
}
}
When I check it via console or via GUI Text preview and I found that it was sorted not completely alphabetical and numerical but lexicographical. (See example below.)
/**
*
* EXPECTED, RESULT IN OUTPUT: (Correct)
* Club 1
* Club 2
* Club 10
* Diamond 5
* Diamond 6
* Heart 10
* Spade 1
* Spade 2
* Spade 10
*
* REALITY, RESULT IN OUTPUT: (Wrong)
* Club 1
* Club 10
* Club 2
* Diamond 5
* Diamond 6
* Heart 10
* Spade 1
* Spade 10
* Spade 2
*
* (Sometimes, it display the result by sorting the one with numbers in lexical order
* first before the letters.)
*
* Ex. "Hearts 1, Clubs 3, Spade 3, Diamonds 4, Diamonds 5"
*
*/
I found this source useful and the only way to sort game object by name is to sort alphabetically and numerically in order to met the result for my card game so that I can use it to compute for the end game results. Currently, I still looking for this answer for this problem about this sorting problem. A contribution for help or tip will be appreciated.
UPDATE (As of 8/6/2015): After I observed their answers about IComparer
syntaxes, I check on this link and I made this solution (with Comparison<GameObject>
as the parameter of the Sort()
method) like this:
cardOrder = this.card[playerIndex];
cardOrder.Sort((s1, s2)=>{
string pattern = "([A-Za-z])([0-9]+)";
string h1 = Regex.Match(s1.name, pattern).Groups[1].Value;
string h2 = Regex.Match(s2.name, pattern).Groups[1].Value;
if (h1 != h2) return h1.CompareTo(h2);
string t1 = Regex.Match(s1.name, pattern).Groups[2].Value;
string t2 = Regex.Match(s2.name, pattern).Groups[2].Value;
return int.Parse(t1).CompareTo(int.Parse(t2));
});
Unfortunately, I still got errors yet. This error message shown in the console like this:
FormatException: Input string was not in the correct format
System.Int32.Parse (System.String s) (at /Users/builduser/buildslave/mono-runtime-and-classlibs/build/mcs/class/corlib/System/Int32.cs:629)
CardInHand.<ResortAndRegroupCard>m__0 (UnityEngine.GameObject s1, UnityEngine.GameObject s2) (at Assets/Bet Module/CardInHand.cs:594)
System.Array.qsort[GameObject] (UnityEngine.GameObject[] array, Int32 low0, Int32 high0, System.Comparison`1 comparison) (at /Users/builduser/buildslave/mono-runtime-and-classlibs/build/mcs/class/corlib/System/Array.cs:1772)
And, in order to re-arrange string value from a GameObject
name (since I created a List
object for storing a lot of GameObjects
) is to find out how to sort a List
of GameObjects
by fetching its name as string value and compare it in order to arrange in alpha-numeric order.
That's a good one. But though, I still want to know how to arrange them in alpha-numerical order.
I added additional info updated. (See section: UPDATE (As of 8/6/2015))
Answer by NeverHopeless · Jul 31, 2015 at 08:26 AM
There is no direct procedure to achieve this you need custom ordering. As a quick guideline, i came up with a simple sample:
List<string> ls = new List<string> (new string[] {"Club 1","Club 10","Club 2","Diamond 5","Diamond 6","Heart 10","Spade 1","Spade 10","Spade 2"});
for(int i = 0; i <ls.Count;i++) {
Match m = Regex.Match (ls[i], "(\\d+)");
string num = m.ToString().PadLeft(5, '0');
ls[i] = ls[i].Replace(m.ToString(), num);
print(ls[i]);
}
// order based on padded results
var data = ls.OrderBy((c) => c);
for(int i = 0; i < data.Count(); i++) {
print (Regex.Replace(data.ElementAt(i), "([0]+)([1-9]+)", "$2"));
}
You can also find dozens of examples to achieve this. Following are the recommended reads:
Alphanumeric sorting using LINQ
How to sort number in alphanumeric
EDIT:
Based on your comment i am adding a bit of explanation, see if it helps to fix your current code.
My first for loop prefix the number with zeros, so the numbers have equal length:
Club 00001 Club 00010 Club 00002
At this point the comparer's default behavior evaluates that it should appear in this sequence:
Club 00001 Club 00002 Club 00010
This is our desired result, but without leading zeros, so my second for loop fixes it and makes:
Club 1 Club 2 Club 10
which is the desired result.
@$$anonymous$$_29, didn't you tried the one i suggested? ls
in my case is this.card[0]
in your case.
@NeverHopeless I tried yours...as my reference. I took the two links you've gave me to further gain more ideas about how to compare two objects in order to sort GameObject
in alpha-numerical. Attempting to re-arrange all GameObjects
in a List
by sorting through getting the the string value of each GameObject's
name and setup the parameter for method in what kind of way of arranging in order within Sort()
method or OrderBy()
method of the List
object. I haven't fully understand yet.
@NeverHopeless ...Where this.card[0]
is the object name of List<GameObject>
.
Ok what did you get when you used my code in place of your's Sort(s1, s2) ?
@NeverHopeless The middle one. Tried but no luck yet. Just straight and see if it works before re-modifying the code for arranging GameObject in alpha-numeric.
Answer by GiyomuGames · Jul 31, 2015 at 07:18 AM
I found this which may solve your problem: http://www.dotnetperls.com/alphanumeric-sorting
Your answer
Follow this Question
Related Questions
A node in a childnode? 1 Answer
How to sort a list of gameobjects by their name? 4 Answers
Sort List by another List Values - Different Type 1 Answer
Sort list with non-anonymous delegate? 2 Answers
merge sort crash Unity 2 Answers