Apollo
Apollo

Reputation: 2070

List Sorting numbers in Descending Order

I have a List that is not sorting at all. I used the .Sort and is not working. I want the numbers to sort in Descending order. 9,6,4,3,2

 List<string> tem = new List<string>();
 using (SqlConnection cs = new SqlConnection(connStr))
 {
       cs.Open();

       for (int x = 0; x < length; x++)
       {
           SqlCommand select = new SqlCommand("spTicketIssuance_GetTransactions", cs);
                select.CommandType = System.Data.CommandType.StoredProcedure;
                select.Parameters.AddWithValue("@TransDesc", TransType[x]);

            SqlDataReader dr = select.ExecuteReader();

            while (dr.Read())
            {
                tem.Add(dr["TransTime"].ToString()); //Adds all Transaction in the multiline textbox and adds them to List  TransList
            }
            dr.Close();
       }
            tem.Sort(); //NOT SORTING
            cs.Close();
        }

Upvotes: 1

Views: 30688

Answers (4)

Roman M
Roman M

Reputation: 578

var names = new List<string> { "abc", "xyz" };
var srotedDesc = names.OrderByDescending(x => x).ToList();

Upvotes: 0

Andrew Cooper
Andrew Cooper

Reputation: 32576

You say you're sorting numbers, but your list contains strings. Sorting numerical values in strings will lead to all sorts of weird results if the numbers have differing numbers of digits.

This is exactly the problem with the sample you gave in your comment. The string sort compares the first character (digit) and sees that 1 < 2, so it sorts 12 before 2. If you started with "2", "12", "7", you'd see it produce the same result - "12", "2", "7".

If you're storing numeric values, use a numeric type for your list.

Also, Sort() will always sort in ascending order. If you want it to produce a descending result you'd either need to Reverse() the result, or, as other answers have said, use OrderByDescending(x => x) instead of Sort(). The latter option would be more efficient.

Update

I take it from your comment on @Steve's answer that the data type in the database is a character type as well?

For your text box you can do something like:

string[] lines = text.Split(Environment.NewLine, StringSplitOptions.RemoveEmptyEntries);
List<int> trans = lines.Select(line => Int32.Parse(line)).ToList();

The second line will blow up if the entries aren't purely numerical, though. A safer way would be something like this:

IEnumerable<int?> values = lines.Select(line => 
{
    int value; 
    return Int32.TryParse(line, out value) ? (int?)value : null;
})
List<int> trans = values.Where(v => v.HasValue).Select(v => v.Value).ToList();

This will discard any lines that can't be converted to an int.

Once you've got your data in numeric format, then store it in the database that way, and the rest of your processing (sorting, etc) becomes a lot easier.

Update 2

Like I said in my comment, the OrderByDescending() method doesn't change the list it's applied to, but essentially provides a different enumeration order over that list. If you need the results in a list just add ToList() to do that. So:

List<int> sortedTrans = transInt.OrderByDescending(x => x).ToList();

Upvotes: 3

Steve
Steve

Reputation: 216293

You could try with

var ordered = tem.OrderByDescending(x => x);

However, given the fact that you add numbers as strings, you can't get a correct order if your numbers are two digits or more.

For example

List<string> tem = new List<string>() {"11", "5", "4"};
var ordered = tem.OrderByDescending(x => x);
foreach(string s in ordered)
     Console.WriteLine(s);

will give you "5", "4", "11" because the first character "5" is greater that the first character "1" in the "11" string. You could add the string with a format specifier that adds the character for zero like this

tem.Add(string.Format("{0:D3}", dr["TransTime"])); 

and have your output correctly sorted (unless you have numbers of 4 digits and more)

EDIT: Example using a List(Of Integer) instead of a List(Of String) and put the result in a textbox

List<int> tem = new List<int>();
using (SqlConnection cs = new SqlConnection(connStr))
{
    .....
    tem.Add(Convert.ToInt32(dr["TransTime"])); 
}

var ordered = tem.OrderByDescending(x => x).ToList();
StringBuilder sb = new StringBuilder();
ordered.ForEach(x => sb.AppendLine(x.ToString()));
textBox.Text = sb.ToString();

Upvotes: 2

BradW
BradW

Reputation: 79

use the

list.OrderByDescending

Would help

Upvotes: 1

Related Questions