2

Hello i do want a sort an array, that contains this:

String[] info = new String[5]{"6,j", "7,d", "12,s", "4,h", "14,s" };

But if i use this:

Array.Sort(info);

The output becomes:

"7,d"
"6,j"
"4,h"
"14,s"
"12,s"

But i wont the output to be:

"14,s"
"12,s"
"7,d"
"6,j"
"4,h"

What is the easiest way to do it in/with C#??

And i cant get Alphanumeric sort to work when i do like this:

Array.Sort(info, new AlphanumComparatorFast());

the type or namespace "AlphanumComparatorFast" could not be found are you missing a using directive or an assembly reference

is the error that i get...

TreyE
  • 2,649
  • 22
  • 24
flaimme
  • 99
  • 3
  • 13

6 Answers6

11

try with:

var sortedArray = info.OrderBy(s=>int.Parse(s.Split(',')[0])).ToArray();

This sorts just by the numeric part, but you can elaborate on that sample. This code strongly assumes that there is always the comma separator, this may be is an issue in production, do some more accurate error handling. Should the array contains some elements that does not conform the exception, providing that is acceptable to ignore the failing elements, we can write:

 var sortedArray = info.Where(k=>!string.IsNullOrEmpty(k)&&k.IndexOf(",")!=-1)
.OrderBy(s=>int.Parse(s.Split(',')[0])).ToArray();
Felice Pollano
  • 32,832
  • 9
  • 75
  • 115
  • thanks a lot now i just have one problem the array i do us is 35 big, how can i modify this to work with that?? :) – flaimme Jan 16 '12 at 21:34
  • ok but when i try it out like this: `static void Main(string[] args) { String[] info = new String[5] { "6,j", "7,d", "12,s", "4,h", "14,s" }; info.OrderBy(s => int.Parse(s.Split(',')[0])).ToArray(); for (int i = 0; i < 5; i++) Console.WriteLine(info[i]); Console.ReadLine(); }` it wont work...?? – flaimme Jan 16 '12 at 22:11
  • Tanks it seems to work but, I do have a last prolen now it wil not work, when i put it in the "real deal" it is a 35 long array that maybe not is full and tend to be about 3-7 full. "formatexception was unhandled" was the error. – flaimme Jan 17 '12 at 09:28
  • 1
    @flaimme yes this is the error handling part, I'll improve the answer again – Felice Pollano Jan 17 '12 at 10:57
2

Rather than represent these as strings, you could parse them and split them out into a class. Implement IComparable and you're sorted. Pun fully intended.

Or, implement your own sort comparator to parse the objects and then sort them correctly.

Alexander R
  • 2,468
  • 24
  • 28
2

you can use a custom comparer

public class MyComparer : IComparer<string>
{
    public int Compare(string x, string y)
    {
        // return value greater than zero if x is greater than y
        // return zero if x is equal to y
        // return value less than zero if x is less than y
    }
}

and you can use your comparer like so

Array.Sort(info, new MyComparer());
  • grate this do seem to work nice when testing it, but when i implement it to the "real" code i i do get the error: argumentoutofrangeexception was unhandled by user code (and a lot of more) but the problem do seem to be: a = "16,h" and number= "16" how can i fix this(and 16 is the highest number it come to be)?? thanks – flaimme Jan 16 '12 at 22:09
  • what does your comparer look like? can you post a sample of it in your question? – Sam I am says Reinstate Monica Jan 16 '12 at 22:13
2

If you're using .NET 2.0 and unable to use Linq you can try:

 String[] info = new String[5] { "6,j", "7,d", "12,s", "4,h", "14,s" };
            Array.Sort(info, delegate(string a, string b)
            {
                int numberA = int.Parse(a.Substring(0, a.IndexOf(',')));
                int numberB = int.Parse(b.Substring(0, b.IndexOf(',')));

                string stringA = a.Substring(a.IndexOf(','));
                string stringB = b.Substring(b.IndexOf(','));

                if (numberA > numberB) return -1;
                else if (numberA < numberB) return 1;
                else return stringA.CompareTo(stringB);
            }
                );

This assumes the separator is always a comma, add your own validation code if needed.

nan
  • 19,595
  • 7
  • 48
  • 80
  • grate this do seem to work nice when testing it, but when i implement it to the "real" code i i do get the error: argumentoutofrangeexception was unhandled by user code (and a lot of more) but the problem do seem to be: a = "16,h" and number= "16" how can i fix this(and 16 is the highest number it come to be)?? thanks – flaimme Jan 16 '12 at 22:15
1

Sorting on the numeric part of the string:

var info = new String[5]{"6,j", "7,d", "12,s", "4,h", "14,s" };
foreach (var item in info.OrderByDescending (x => 
                                   int.Parse(x.Substring(0, x.IndexOf(',')))))
{
    Console.WriteLine(item);
}
Magnus
  • 45,362
  • 8
  • 80
  • 118
1

Here is a bit of code I wrote a while ago, I'm sure there's a more efficient way to do it, but this certainly works. To use it, include:

using System.Linq;

then call use a linq query:

Array.Sort(info,delegate(string x, string y){return NaturalCompare(y,x)}); sort as you seem to want

and of course include the relevant method:

    public int NaturalCompare(string x, string y)
    {
        string[] x1, y1;
        x1 = Regex.Split(x.Replace(" ", ""), "([0-9]+)");
        y1 = Regex.Split(y.Replace(" ", ""), "([0-9]+)");
        for (int i = 0; i < x1.Length && i < y1.Length; i++)
        {
            if (!x1[i].Equals(y1[i]))
            {
                return PartCompare(x1[i], y1[i]);
            }
        }
        return x.CompareTo(y);
    }

    private int PartCompare(string left, string right)
    {
        int x, y;
        if (int.TryParse(left, out x) && int.TryParse(right, out y))
            return x.CompareTo(y);
        return left.CompareTo(right);
    }
Jeff Lauder
  • 1,247
  • 8
  • 14