简体   繁体   中英

Sorting a List alphabetically and numerically

I've written a code that has a list and I want to sort the list alphabetically and numerically.

For example the first items in the list are

  • list[0] = "INPUT 10"
  • list[1] = "INPUT 5" .

I want my list reorganized like this:

  • list[0] = "INPUT 5"
  • list[1] = "INPUT 10" .

So basically my program gets checked items from a checked list box,stores them in a list, and I want it to reorganize the list alphabettically.

The checked list box has items like INPUT 1,INPUT 2,INPUT 3...and so fourth. Can anyone suggest me a way of how to go about this?

UPDATED CODE

I've updated my code and now this code splits the strings into INPUT and 10.The "q" list obtains the checked items in the input box,the string "s" array gets the splittd data from the q list. Then the "numbers" list gets only the number part of the string for example "INPUT 5",the number list will only get "5".Then I want to sort these numbers and build another string combining the sorted number list and the string "INPUT" and add it to the output checkedlistbox. My code isnt working though...any suggestions?It should sort the numbers but it doesnt...anyone have any suggestions of why this code isnt working? And I keep on getting error messages of the array being able to unhandle negative integers and what not.

    List<string> q = new List<string>();
    List<string> numbers = new List<string>();

    private void button_ekle_Click(object sender, EventArgs e)
    {




        for (int k = clb_input.Items.Count - 1; k >= 0; k--)
        {
            if (clb_input.GetItemChecked(k) == true)
            {
                q.Add(clb_input.Items[k].ToString());


                //clb_output.Items.Add(clb_input.Items[k]);
                clb_input.Items.RemoveAt(k);

            }
            else { }
        }

        string[] s = new string[q.Count * 2];

        //string[] numbers=new string[q.Count/2];
        for (int t = 1; t <= q.Count * 2; t++)
        {
            if (q != null)
                s = q[t - 1].ToString().Split(' ');
            else { s[t] = null; }

        }
        for (int x = 1; x <= q.Count; x++)
        {
            if (s[2 * x - 1] != null)
            {
                numbers[x - 1] = s[2 * x - 1];
                numbers.Sort();
                clb_output.Items.Add("INPUT "+ numbers[x - 1].ToString());
            }
            else { numbers[x - 1] = null; }
        } 



    }

What you need is Alphanumeric Sorting ( most commonly seen in windows explorer, the way files are sorted)

Code can be found here : http://www.dotnetperls.com/alphanumeric-sorting

Sample

class Program
{
    static void Main()
    {
    string[] highways = new string[]
    {
        "100F",
        "50F",
        "SR100",
        "SR9"
    };
    //
    // We want to sort a string array called highways in an
    // alphanumeric way. Call the static Array.Sort method.
    //
    Array.Sort(highways, new AlphanumComparatorFast());
    //
    // Display the results
    //
    foreach (string h in highways)
    {
        Console.WriteLine(h);
    }
    }
}

Output

50F
100F
SR9
SR100

Implementation

public class AlphanumComparatorFast : IComparer
{
    public int Compare(object x, object y)
    {
    string s1 = x as string;
    if (s1 == null)
    {
        return 0;
    }
    string s2 = y as string;
    if (s2 == null)
    {
        return 0;
    }

    int len1 = s1.Length;
    int len2 = s2.Length;
    int marker1 = 0;
    int marker2 = 0;

    // Walk through two the strings with two markers.
    while (marker1 < len1 && marker2 < len2)
    {
        char ch1 = s1[marker1];
        char ch2 = s2[marker2];

        // Some buffers we can build up characters in for each chunk.
        char[] space1 = new char[len1];
        int loc1 = 0;
        char[] space2 = new char[len2];
        int loc2 = 0;

        // Walk through all following characters that are digits or
        // characters in BOTH strings starting at the appropriate marker.
        // Collect char arrays.
        do
        {
        space1[loc1++] = ch1;
        marker1++;

        if (marker1 < len1)
        {
            ch1 = s1[marker1];
        }
        else
        {
            break;
        }
        } while (char.IsDigit(ch1) == char.IsDigit(space1[0]));

        do
        {
        space2[loc2++] = ch2;
        marker2++;

        if (marker2 < len2)
        {
            ch2 = s2[marker2];
        }
        else
        {
            break;
        }
        } while (char.IsDigit(ch2) == char.IsDigit(space2[0]));

        // If we have collected numbers, compare them numerically.
        // Otherwise, if we have strings, compare them alphabetically.
        string str1 = new string(space1);
        string str2 = new string(space2);

        int result;

        if (char.IsDigit(space1[0]) && char.IsDigit(space2[0]))
        {
        int thisNumericChunk = int.Parse(str1);
        int thatNumericChunk = int.Parse(str2);
        result = thisNumericChunk.CompareTo(thatNumericChunk);
        }
        else
        {
        result = str1.CompareTo(str2);
        }

        if (result != 0)
        {
        return result;
        }
    }
    return len1 - len2;
    }
}

You can use Sort with a Comparer like this:

List<string> q = new List<string>();

private void button_ekle_Click(object sender, EventArgs e)
{
    for (int k=clb_input.Items.Count-1; k >= 0; k--)
    {
        if (clb_input.GetItemChecked(k) == true)
        {
            q.Add(clb_input.Items[k].ToString());
            clb_input.Items.RemoveAt(k);
        }
        else { }
    }
    q.Sort((p1,p2)=>((int)(p1.split(" ")[1])).CompareTo((int)(p2.split(" ")[1])));
    for (int t = 0; t < q.Count; t++)
    {
        clb_output.Items.Add(q[t].ToString());
    }
}

The simplest solution is to just left-pad the numerical values with a space to the same length.

List<string> lst = new List<string>
{
    "Item   9",
    "Item  999",
    "Thing 999",
    "Thing   5",
    "Thing   1",
    "Item  20",
    "Item  10",
};
lst.Sort();

Output:

Item   9 
Item  10 
Item  20 
Item  999 
Thing   1 
Thing   5 
Thing 999 

And you can always remove the extra white space used for padding after the sorting operation is performed.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM