473,396 Members | 2,090 Online
Bytes | Software Development & Data Engineering Community
Post Job

Home Posts Topics Members FAQ

Join Bytes to post your question to a community of 473,396 software developers and data experts.

Order Text as Numbers

Hi,

I am currently writing a requirements gathering system which which
have requirement values of 1.1, 1.1.2, 1.1.3, 2.3.4.5 etc etc.

This works fine stored as varchar in SQL Server 2000 until I want to
sort it in a .Net datagrid. As soon as I reach 10, it obviously puts
the record down with the 1's and I am guessing 20 will go with the 2's
etc etc.

Can anyone suggest a way of getting round this - I know it is because
of the details being stored as text but I need some sort of solution.

Thanks
Nov 16 '05 #1
5 2575
Hi Dave,

You could create a struct out of a single string for the text and have the struct implement IComparable. Putting the structs inside any list with a Sort method should sort it according to your needs.

The CompareTo method will be called on each object to determine if it is "larger" or "smaller" or "equal" to some other object.

ArrayList list = new ArrayList();

RequirementNumber r = new RequirementNumber();
r.Number = "1.1";
list.Add(r);

r = new RequirementNumber();
r.Number = "1.10";
list.Add(r);

r = new RequirementNumber();
r.Number = "1.2";
list.Add(r);

r = new RequirementNumber();
r.Number = "1.1.1";
list.Add(r);

list.Sort();
The list will now be

1.1
1.1.1
1.2
1.10

If this is not the way you want it sorted, just changed the code to what you need.

public struct RequirementNumber : IComparable
{
public string Number;

public int CompareTo(object o) // this method will be called by Sort()
{
if(!(o is RequirementNumber))
return -1;

RequirementNumber temp = (RequirementNumber)o;

string[] local = Number.Split(new char[]{'.'});
string[] remote = temp.Number.Split(new char[]{'.'});

int[] numlocal = new int[local.Length];
int[] numremote = new int[remote.Length];

for(int i = 0; i < local.Length; i++)
{
string s = (string)local[i];
try
{
numlocal[i] = Int32.Parse(s);
}
catch
{
numlocal[i] = 0;
}
}

for(int i = 0; i < remote.Length; i++)
{
string s = (string)remote[i];
try
{
numremote[i] = Int32.Parse(s);
}
catch
{
numremote[i] = 0;
}
}

for(int i = 0; i < numlocal.Length; i++)
{
if(numlocal[i] < numremote[i]) // X.1.X < X.2.X
return -1;
else if(numlocal[i] > numremote[i]) // >
return 1;
// else equal and we need to check the next step
if(i == numremote.Length -1) // X.X > X.X.X
return 1;
}

if(numremote.Length > numlocal.Length) // X.X.X < X.X
return -1;

return 0; // numbers are equal
}
}
Happy coding!
Morten Wennevik [C# MVP]
Nov 16 '05 #2
assuming there are never more than 99 sub-requirements for a single
requirement, you can store them in the database as System.Decimal:
1.1 -> 1.01
1.1.2 -> 1.0102
1.1.3 -> 1.0103
2.3.4.5 -> 2.030405

etc.
then they will be sorted correctly.

Dave wrote:
Hi,

I am currently writing a requirements gathering system which which
have requirement values of 1.1, 1.1.2, 1.1.3, 2.3.4.5 etc etc.

This works fine stored as varchar in SQL Server 2000 until I want to
sort it in a .Net datagrid. As soon as I reach 10, it obviously puts
the record down with the 1's and I am guessing 20 will go with the 2's
etc etc.

Can anyone suggest a way of getting round this - I know it is because
of the details being stored as text but I need some sort of solution.

Thanks

Nov 16 '05 #3
Hi,

I think there is a better way of doing this, instead of implementing a
struct that needs to be carry out with the data just create a class that
implement IComparer. Then you can use Array.Sort with this IComparer.

This is how it will looks:
public class NumberingSorter: IComparer
{
public int Compare(object x, object y)
{
if ( (x== null ) && (y==null) )
return 0;
if ( x == null )
return -1;
if ( y == null )
return 1;
// convert to string
string x1 = x.ToString();
string y1 = y.ToString();
//now split the str
string[] partsX = x1.Split( new char[] { '.' } );
string[] partsY = y1.Split( new char[] { '.' } );

//You should put this on a cycle !!!
if ( partsX[0] > partsY[0] )
return 1;

if ( partsX[0] < partsY[0] )
return -1;

// If they are equal pass to the next one
}

}

Please note that I adapted the above code from another class with a similar
functionality and you will have to refine it, the logic is there though.

Cheers,

--
Ignacio Machin,
ignacio.machin AT dot.state.fl.us
Florida Department Of Transportation

"Morten Wennevik" <Mo************@hotmail.com> wrote in message
news:opr80kcujeklbvpo@morten_x.edunord...
Hi Dave,

You could create a struct out of a single string for the text and have the struct implement IComparable. Putting the structs inside any list with a
Sort method should sort it according to your needs.
The CompareTo method will be called on each object to determine if it is "larger" or "smaller" or "equal" to some other object.
ArrayList list = new ArrayList();

RequirementNumber r = new RequirementNumber();
r.Number = "1.1";
list.Add(r);

r = new RequirementNumber();
r.Number = "1.10";
list.Add(r);

r = new RequirementNumber();
r.Number = "1.2";
list.Add(r);

r = new RequirementNumber();
r.Number = "1.1.1";
list.Add(r);

list.Sort();
The list will now be

1.1
1.1.1
1.2
1.10

If this is not the way you want it sorted, just changed the code to what you need.
public struct RequirementNumber : IComparable
{
public string Number;

public int CompareTo(object o) // this method will be called by Sort()
{
if(!(o is RequirementNumber))
return -1;

RequirementNumber temp = (RequirementNumber)o;

string[] local = Number.Split(new char[]{'.'});
string[] remote = temp.Number.Split(new char[]{'.'});

int[] numlocal = new int[local.Length];
int[] numremote = new int[remote.Length];

for(int i = 0; i < local.Length; i++)
{
string s = (string)local[i];
try
{
numlocal[i] = Int32.Parse(s);
}
catch
{
numlocal[i] = 0;
}
}

for(int i = 0; i < remote.Length; i++)
{
string s = (string)remote[i];
try
{
numremote[i] = Int32.Parse(s);
}
catch
{
numremote[i] = 0;
}
}

for(int i = 0; i < numlocal.Length; i++)
{
if(numlocal[i] < numremote[i]) // X.1.X < X.2.X
return -1;
else if(numlocal[i] > numremote[i]) // >
return 1;
// else equal and we need to check the next step
if(i == numremote.Length -1) // X.X > X.X.X
return 1;
}

if(numremote.Length > numlocal.Length) // X.X.X < X.X
return -1;

return 0; // numbers are equal
}
}
Happy coding!
Morten Wennevik [C# MVP]

Nov 16 '05 #4
Yes Ignacio, Array.Sort with IComparer is probably far better. You learn something every day :)

In this case, drop the struct, make a new class and use an instance of the class to sort an array of strings.

string[] test = new string[]{"1.1", "1.10", "1.2", "1.1.1"};
SortClass sc = new SortClass();
Array.Sort(test, 0, test.Length, sc);

This should sort the strings in the same way as my other example.

public class SortClass : IComparer
{
public int Compare(object x, object y)
{
if(!(x is String) || !(y is string))
return -1;

string X = (string)x;
string Y = (string)y;

string[] local = X.Split(new char[]{'.'});
string[] remote = Y.Split(new char[]{'.'});

int[] numlocal = new int[local.Length];
int[] numremote = new int[remote.Length];

for(int i = 0; i < local.Length; i++)
{
string s = (string)local[i];
try
{
numlocal[i] = Int32.Parse(s);
}
catch
{
numlocal[i] = 0;
}
}

for(int i = 0; i < remote.Length; i++)
{
string s = (string)remote[i];
try
{
numremote[i] = Int32.Parse(s);
}
catch
{
numremote[i] = 0;
}
}

for(int i = 0; i < numlocal.Length; i++)
{
if(numlocal[i] < numremote[i]) // X.1.X < X.2.X
return -1;
else if(numlocal[i] > numremote[i]) // >
return 1;
// else equal and we need to check the next step
if(i == numremote.Length -1) // X.X > X.X.X
return 1;
}

if(numremote.Length > numlocal.Length) // X.X.X < X.X
return -1;
return 0; // numbers are equal
}
}
Happy coding!
Morten Wennevik [C# MVP]
Nov 16 '05 #5
Thanks very much for all your help everyone. It seems there are some
great answers which I can have a bash at.

Thanks again

Dave
Nov 16 '05 #6

This thread has been closed and replies have been disabled. Please start a new discussion.

Similar topics

2
by: Alpay Eno | last post by:
Hello all... I'm using asp to get records from an access database, very similar to the way datagrid would work. The title of each column in my table is a link that alternates the sort order between...
0
by: EddieA | last post by:
Does anyone know how to set the Sort Order for a Pivot Table when you want the data to be sorted on a field that is available but not placed on the Pivot Table. My situation is that I've got...
4
by: Deborah V. Gardner | last post by:
I have a field with values like this CO 03-10 CO 03-4 VI 03-8 CO 03-533 I would like these to sort for a report by the first two letters and the digits after the hyphen (-) like this
5
by: Ataru Morooka | last post by:
Hi, my table has to have a column with the months names (january, february...). When I order it by month it is ordered alphabetically and that's not what I need. Reading this ng I found someone...
7
by: Giles | last post by:
An ASP page outputs data from the query "Select ThisAndThat from comments WHERE pageURL='" & pageURL & "' ORDER BY threadID, datesent" (Access mdb) threadID is a string (OK, I know!), which means...
2
by: phillip.s.powell | last post by:
SELECT s.id, s.first_name, s.last_name, IF(s.school_year_id = 0, s.school_year_other, y.school_year_alt_display) AS school_year_name FROM student s LEFT OUTER JOIN school_year y ON...
2
by: hazz | last post by:
is there a way to have a re-arrangeable list with an asp.net control ? I would like to have a list of database table column values in an ordered list initially loaded by their column order in the...
1
by: Jon | last post by:
I am sure this has been covered before, but I'm not having luck finding much that's useful. I use a single web page that has several text inputs and other controls, including a couple of...
1
maxamis4
by: maxamis4 | last post by:
Hello folks, I have two forms a parent form and a subform. The parent form is an unbound form while the subform is a form that contains all a list of what I like to call 'in stock ' phone...
0
by: Charles Arthur | last post by:
How do i turn on java script on a villaon, callus and itel keypad mobile phone
0
by: ryjfgjl | last post by:
In our work, we often receive Excel tables with data in the same format. If we want to analyze these data, it can be difficult to analyze them because the data is spread across multiple Excel files...
0
by: emmanuelkatto | last post by:
Hi All, I am Emmanuel katto from Uganda. I want to ask what challenges you've faced while migrating a website to cloud. Please let me know. Thanks! Emmanuel
0
BarryA
by: BarryA | last post by:
What are the essential steps and strategies outlined in the Data Structures and Algorithms (DSA) roadmap for aspiring data scientists? How can individuals effectively utilize this roadmap to progress...
1
by: nemocccc | last post by:
hello, everyone, I want to develop a software for my android phone for daily needs, any suggestions?
1
by: Sonnysonu | last post by:
This is the data of csv file 1 2 3 1 2 3 1 2 3 1 2 3 2 3 2 3 3 the lengths should be different i have to store the data by column-wise with in the specific length. suppose the i have to...
0
Oralloy
by: Oralloy | last post by:
Hello folks, I am unable to find appropriate documentation on the type promotion of bit-fields when using the generalised comparison operator "<=>". The problem is that using the GNU compilers,...
0
tracyyun
by: tracyyun | last post by:
Dear forum friends, With the development of smart home technology, a variety of wireless communication protocols have appeared on the market, such as Zigbee, Z-Wave, Wi-Fi, Bluetooth, etc. Each...
0
agi2029
by: agi2029 | last post by:
Let's talk about the concept of autonomous AI software engineers and no-code agents. These AIs are designed to manage the entire lifecycle of a software development project—planning, coding, testing,...

By using Bytes.com and it's services, you agree to our Privacy Policy and Terms of Use.

To disable or enable advertisements and analytics tracking please visit the manage ads & tracking page.