Solved

Sorting alphanumeric table column correctly

Posted on 2004-09-24
12
299 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
[X]
Welcome to Experts Exchange

Add your voice to the tech community where 5M+ people just like you are talking about what matters.

  • Help others & share knowledge
  • Earn cash & points
  • Learn & ask questions
  • 4
  • 4
12 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
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!

 
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 75 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

Salesforce Has Never Been Easier

Improve and reinforce salesforce training & adoption using WalkMe's digital adoption platform. Start saving on costly employee training by creating fast intuitive Walk-Thrus for Salesforce. Claim your Free Account Now

Question has a verified solution.

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

In order to hide the "ugly" records selectors (triangles) in the rowheaders, here are some suggestions. Microsoft doesn't have a direct method/property to do it. You can only hide the rowheader column. First solution, the easy way The first sol…
Introduction This article series is supposed to shed some light on the use of IDisposable and objects that inherit from it. In essence, a more apt title for this article would be: using (IDisposable) {}. I’m just not sure how many people would ge…
Michael from AdRem Software outlines event notifications and Automatic Corrective Actions in network monitoring. Automatic Corrective Actions are scripts, which can automatically run upon discovery of a certain undesirable condition in your network.…
Do you want to know how to make a graph with Microsoft Access? First, create a query with the data for the chart. Then make a blank form and add a chart control. This video also shows how to change what data is displayed on the graph as well as form…

695 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