[Last Call] Learn how to a build a cloud-first strategyRegister Now

x
?
Solved

Sorting alphanumeric table column correctly

Posted on 2004-09-24
12
Medium Priority
?
318 Views
Last Modified: 2012-06-27
How can I sort a table column correctly when the table has values like "0", "A1", "AA-1", "B21", "3C", 4-32A", "1", "11-1", 2-A", etc...

Windows Explorer (in XP) seems to do this correctly when I sort files with these names.  In the column, I tried padding all values with 0's and the sorting improved but it still wasn't correct.

Basically, I want to emulate the Windows XP file sorting.
Any help is appreciated.

Thanks.
0
Comment
Question by:MyersA
  • 4
  • 4
9 Comments
 
LVL 4

Expert Comment

by:Jarodtweiss
ID: 12147755
How do you want to sort this ?
For me Windows XP sort me the file like this :
0.txt
1.txt
11-1.txt
2-A.txt
3C.txt
4-32A.txt
A1.txt
AA-1.txt
B21.txt

If you want to sort in another way, I'm using a custom type that implements the IComparable interface.
Can you explain better the sort you want to implement ?
0
 
LVL 2

Author Comment

by:MyersA
ID: 12147774
Yes, that's how I want to sort them.
0
 
LVL 2

Author Comment

by:MyersA
ID: 12147814
Sorry. In my XP Windows Explorer, this is how the sort looks like (the files don't have extensions):

0
1
2-A
3C
4-32A
11-1
A1
AA-1
B1
B21
BB1

Maybe the extensions produce a different order. But I want it sorted like above.
0
Technology Partners: We Want Your Opinion!

We value your feedback.

Take our survey and automatically be enter to win anyone of the following:
Yeti Cooler, Amazon eGift Card, and Movie eGift Card!

 
LVL 15

Expert Comment

by:praneetha
ID: 12147968
string[] temp= this.TextBox2.Text.Split(',');//{"0.txt","1.txt","11-1.txt","2-A.txt","3C.txt","4-32A.txt","A1.txt","AA-1.txt","B21.txt"};
                  Array.Sort(temp);
                  foreach(string s in temp)
                  {
                              this.TextBox1.Text+=s+"*";
                  }


and i enter in textbox2=0.txt,A1.txt,AA-1.txt,B21.txt,1.txt,11-1.txt,2-A.txt,3C.txt,4-32A.txt

and textbox1.text=0.txt*1.txt*11-1.txt*2-A.txt*3C.txt*4-32A.txt*A1.txt*AA-1.txt*B21.txt*

this one sorts like jarodtweiss XP machine ...

0
 
LVL 2

Author Comment

by:MyersA
ID: 12148024
Thanks for the post.

But in my Windows XP 11-1.txt is greater that 2-A.txt . the order would be like this:
0
1
2-A
3C
4-32A
11-1
A1
AA-1
B1
B21
BB1
0
 
LVL 4

Expert Comment

by:Jarodtweiss
ID: 12153856
Hey MyersA !

Here is what I suggest. In such a case, I definitely think that the IComparable interface is the solution you are searching.
If I understand, if you find some figures before the "-", you want to sort on the numeric order. Otherwise, it is the alpahabetical order.

So Maybe that you can do something like that in the CompareTo method:
1. Extract the first caharacter of the string that are numbers.
2. If A has some numbers and B doesn't, then return a negative number (A is before B)
3. If B has some numers and A doesn't then return a positive number
4. If A and B has some numbers return Anumbers.CompareTo(Bnumbers)
4. If A and B doesn't have numbers return A.CompareTo(B)

And this should work !
0
 
LVL 4

Expert Comment

by:Jarodtweiss
ID: 12153916
For extra info, here is what I have done :
(tested in VS.NET 2005, remove the generics so it can be used in previous version)
Note that the IComparable is not correctly written (coule be simplified, no exception if not correct type, ...)
But In the end, I have the correct sort order

    public class XpFileName : IComparable
    {
        string name;

        public XpFileName(string myName)
        {
            name = myName;
        }

        public string Name
        {
            get {return name;}
        }

        public int CompareTo(object myObj)
        {
            XpFileName myFile = (XpFileName)myObj;
            string myObjNumbers = string.Empty;
            string thisNumbers = string.Empty;
            for (int i = 0; i < myFile.name.Length; ++i)
            {
                if (char.IsDigit(myFile.Name[i]))
                    myObjNumbers += myFile.Name[i];
                else
                    break;
            }
            for (int i = 0; i < this.name.Length; ++i)
            {
                if (char.IsDigit(this.Name[i]))
                    thisNumbers += this.Name[i];
                else
                    break;
            }

            if (thisNumbers.Length > 0 && myObjNumbers.Length == 0)
                return this.name.CompareTo(myFile.name);
            if (thisNumbers.Length == 0 && myObjNumbers.Length > 0)
                return this.name.CompareTo(myFile.name);
            if (thisNumbers.Length == 0 && myObjNumbers.Length == 0)
                return this.name.CompareTo(myFile.name);
            if (thisNumbers.Length > 0 && myObjNumbers.Length > 0)
                return Convert.ToInt32(thisNumbers).CompareTo(Convert.ToInt32(myObjNumbers));

            return 0;
        }

        public override string ToString()
        {
            return this.Name;
        }

    }

            List<XpFileName> myList = new List<XpFileName>();
            myList.Add(new XpFileName("BB1"));
            myList.Add(new XpFileName("0"));
            myList.Add(new XpFileName("1"));
            myList.Add(new XpFileName("AA-1"));
            myList.Add(new XpFileName("4-32A"));
            myList.Add(new XpFileName("3C"));
            myList.Add(new XpFileName("B1"));
            myList.Add(new XpFileName("11-1"));
            myList.Add(new XpFileName("A1"));
            myList.Add(new XpFileName("B21"));
            myList.Add(new XpFileName("2-A"));
            Console.WriteLine("Before sort");
            for (int i = 0; i < myList.Count; ++i)
                Console.WriteLine(myList[i]);

            myList.Sort();
            Console.WriteLine("After sort");
            for (int i = 0; i < myList.Count; ++i)
                Console.WriteLine(myList[i]);
        }


0
 
LVL 2

Author Comment

by:MyersA
ID: 12161151
Thanks for the code.
Once I add this code, what do I need to do? All values that I add to the column go through the XpFilename constructor but function CompareTo is never called. I think I'm doing something wrong but I don't know what. Basically, I added a new class with your code and, in the Form. I do this:

DataRow dataRow = DataTableAddress.NewRow();
dataRow["prim_low"] = addr_rec.prim_low.TrimStart('0');  //column seen by user
dataRow["sorter"] = new ZM_Utilities.XpFilename(addr_rec.prim_low.TrimStart('0'));  //column to sort by. Value is full of leading zeroes.
DataTableAddress.Rows.Add(dataRow);

Thanks again.
0
 
LVL 4

Accepted Solution

by:
Jarodtweiss earned 300 total points
ID: 12167341
You do not have to call explicitely the CompareTo method, it is called automatically by the framework when you ask the sorting of a column.
In my example, it is done thru the myList.Sort
In your case, you should try :

DataTableAddress.DefaultView.Sort("sorter");
0

Featured Post

Independent Software Vendors: We Want Your Opinion

We value your feedback.

Take our survey and automatically be enter to win anyone of the following:
Yeti Cooler, Amazon eGift Card, and Movie eGift Card!

Question has a verified solution.

If you are experiencing a similar issue, please ask a related question

Exception Handling is in the core of any application that is able to dignify its name. In this article, I'll guide you through the process of writing a DRY (Don't Repeat Yourself) Exception Handling mechanism, using Aspect Oriented Programming.
This article aims to explain the working of CircularLogArchiver. This tool was designed to solve the buildup of log file in cases where systems do not support circular logging or where circular logging is not enabled
Screencast - Getting to Know the Pipeline
When cloud platforms entered the scene, users and companies jumped on board to take advantage of the many benefits, like the ability to work and connect with company information from various locations. What many didn't foresee was the increased risk…

830 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question