2012-01-16 2 views
2

Привет я хочу своего рода массив, который содержит следующее:C# сортировка ArrayList с фигурами

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

Но если я использую это:

Array.Sort(info); 

Выход становится:

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

Но я не буду производиться:

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

Что является самым простым способом сделать это в/с C#?

И я не могу получить буквенно-цифровой вид, чтобы работать, когда я делаю так:

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

типа или пространства имен «AlphanumComparatorFast» не может быть найден в Соскучились с помощью директивы или ссылка на сборку

это ошибка, я получаю ...

+0

где определен 'AlphanumComparatorFast'? –

+4

Это, вероятно, отсюда: http://www.dotnetperls.com/alphanumeric-sorting Но вам действительно нужно реализовать код ... для его работы ... .NET framework не имеет ничего подобного встроенного в него. –

+0

@flaimme - это не часть .net framework. –

ответ

11

попробуйте:

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

Это похоже на числовую часть, но вы можете подробно остановиться на этом образце. Этот код сильно предполагает, что всегда существует разделитель запятой, это может быть проблемой при производстве, еще более точной обработкой ошибок. Если массив содержит некоторые элементы, которые не соответствуют исключению, при условии, что приемлемо игнорировать неисправный элемент, мы можем написать:

var sortedArray = info.Where(k=>!string.IsNullOrEmpty(k)&&k.IndexOf(",")!=-1) 
.OrderBy(s=>int.Parse(s.Split(',')[0])).ToArray(); 
+2

Я бы добавил дополнительный +1 для поощрения точной обработки ошибок, если бы мог .. –

+0

спасибо большое, теперь у меня только одна проблема: массив, который я делаю, 35, как я могу изменить это, чтобы работать с этим? :) – flaimme

+0

@flaimme Я не понял, как размер массива изменит результат ... –

2

Вместо того, чтобы представлять их в виде строк, можно разобрать их и разделить их в класс. Внедрите IComparable, и вы отсортированы. Pun полностью предназначен.

Или реализуйте свой собственный сортировщик, чтобы проанализировать объекты, а затем отсортировать их правильно.

1

Сортировка по числовой части строки:

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); 
} 
2

вы можете использовать собственный компаратор

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

и вы можете использовать компаратор как так

Array.Sort(info, new MyComparer()); 
+0

Grate это действительно работает хорошо при тестировании, но когда я реализую его в «реальном» коде, я получаю ошибку: аргумент outofrangeexception был необработанным по коду пользователя (и многое другое), но проблема выглядит так: a = "16, h" и number = "16", как я могу это исправить (и 16 - это самое высокое число, которое оно получило)? спасибо – flaimme

+0

Как выглядит ваш компаратор? можете ли вы опубликовать образец этого вопроса в своем вопросе? –

+0

ops я действительно хотел ответить Andrzej Nosal ops ... – flaimme

1

Здесь есть немного кода, который я написал некоторое время назад, я уверен, что есть более эффективный способ сделать это, но это, безусловно, работает. Чтобы его использовать, включают в себя:

using System.Linq; 

затем вызвать использовать Linq запрос:

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

и, конечно, включать соответствующий метод:

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); 
    } 
2

Если вы используете .NET 2.0 и не может использовать Linq, вы можете попробовать:

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); 
      } 
       ); 

Это предполагает, что разделитель всегда является запятой, при необходимости добавьте свой собственный код проверки.

+0

Grate это действительно кажется приятным при тестировании, но когда я реализую его в «реальном» коде, я получу ошибку: аргумент outoutofrangeexception был необработанным кодом пользователя (и многое другое), но проблема кажется: a = "16, h" и number = "16", как я могу это исправить (и 16 - это самое высокое число, которое оно получило)? благодаря – flaimme