2015-01-14 4 views
0

У меня есть класс с одно свойство «Name», содержащие имена, как "1_[AnnualRevenue]","2_[ResellerType]","3_xxx"....Сортировка свойство класса строки поля с числовым значением

мой класс, как

class xxx 
{ 
private string fileName; 
public string FileName 
     { 
      get { return fileName; } 
      set { fileName = value; } 
     } 
} 

И я задаю значения к объекту класса. например xxx.FileName="1_[AnnualRevenue]";

Теперь у меня есть класс списка. А теперь отсортируйте список в соответствии с этим свойством класса.

Теперь я хочу сортировать поле в соответствии с порядком цифр, я имею в виду 1 первую 2 секунды и так далее.

И затем напишите его в filestream.

Может ли любой орган помочь мне в этом. Спасибо заранее.

+2

вы хотите сказать, у вас есть список классов, которые вы хотите, чтобы отсортировать их собственности Name? Было бы полезно, если бы вы показали образец кода класса и как вы храните его экземпляры. –

+0

показать свой класс и пример значений –

+0

Вы говорите о номерах «N_» в начале имени вашего файла? –

ответ

2

Поскольку свойство является String, но вы хотите отсортировать его численно, вероятно, лучше всего было бы реализовать IComparable, а затем введите свой собственный код сортировки в методе CompareTo. Тогда вам не нужно писать более сложный оператор Lambda каждый раз, когда вы хотите сортировать список, вы можете просто вызвать метод Sort() в списке.

Вы также можете обрабатывать случаи, когда FileName свойство не содержит подчеркивание или является null, а не получать исключения в вашем OrderBy кода (что случилось бы с большинством других ответов).

Я сделал несколько других изменений также - переопределить метод ToString, так что вы можете легко отображать значение в окне консоли, и используется автоматический синтаксис свойств для FileName собственности, поэтому мы можем удалить поле подкладочный:

class xxx : IComparable<xxx> 
{ 
    public string FileName { get; set; } 

    public int CompareTo(xxx other) 
    { 
     // Short circuit if any object is null, if the 
     // Filenames equal each other, or they're empty 
     if (other == null) return 1; 
     if (FileName == null) return (other.FileName == null) ? 0 : -1; 
     if (other.FileName == null) return 1; 
     if (FileName.Equals(other.FileName)) return 0; 
     if (string.IsNullOrWhiteSpace(FileName)) 
      return (string.IsNullOrWhiteSpace(other.FileName)) ? 0 : -1; 
     if (string.IsNullOrWhiteSpace(other.FileName)) return 1; 

     // Next, try to get the numeric portion of the string to compare 
     int thisIndex; 
     int otherIndex; 

     var thisSuccess = int.TryParse(FileName.Split('_')[0], out thisIndex); 
     var otherSuccess = int.TryParse(other.FileName.Split('_')[0], out otherIndex); 

     // If we couldn't get the numeric portion of the string, use int.MaxValue 
     if (!thisSuccess) 
     { 
      // If neither has a numeric portion, just use default string comparison 
      if (!otherSuccess) return FileName.CompareTo(other.FileName); 
      thisIndex = int.MaxValue; 
     } 
     if (!otherSuccess) otherIndex = int.MaxValue; 

     // Return the comparison of the numeric portion of the two filenames 
     return thisIndex.CompareTo(otherIndex); 
    } 

    public override string ToString() 
    { 
     return FileName; 
    } 
} 

Теперь, вы можете просто позвонить Sort в списке:

List<xxx> list = new List<xxx> 
{ 
    new xxx {FileName = "13_a"}, 
    new xxx {FileName = "8_a"}, 
    new xxx {FileName = null}, 
    new xxx {FileName = "1_a"}, 
    new xxx {FileName = "zinvalid"}, 
    new xxx {FileName = "2_a"}, 
    new xxx {FileName = ""}, 
    new xxx {FileName = "invalid"} 
}; 

list.Sort(); 

Console.WriteLine(string.Join("\n", list)); 

// Output (note the first two are the empty string and the null value): 
// 
// 
// 1_a 
// 2_a 
// 8_a 
// 13_a 
// invalid 
// zinvalid 
+0

Кстати, не уверен, как вы подходите FileNames, но если вы добавляете номер в них где-то в коде, возможно, было бы проще просто присвоить классу свойство int Rank {get; set;} 'и установить его в дополнение к FileName. Если вы это сделали, вы можете просто сделать: 'list.OrderBy (i => i.Rank)', и вам не нужно будет создавать собственный метод CompareTo. –

2

Вы можете использовать LINQ, чтобы сделать это для вас

List<xxx> orderedList = unOrderedList.OrderBy(o => Convert.ToInt32(o.FileName.Split('_').First())).ToList(); 

Editted ответ на имени комментариев - указывая на то, что на самом деле нам нужно преобразовать в целые числа, чтобы правильно заказать.

+0

Куда бы это положило 10_a, 20_a, решение такое же, как и выше –

+0

Хотя мне нужно попробовать, но это звучит неплохо, чистое числовое упорядочение –

2

Вы можете сделать, как следующее для сортировки списка:

List<xxx> list = new List<xxx> 
{ 
    new xxx { FileName = "3_a" }, 
    new xxx { FileName = "1_a" }, 
    new xxx { FileName = "2_a" }, 
    new xxx { FileName = "8_a" } 
}; 
var sorted = list.OrderBy(it => Convert.ToInt32(it.FileName.Split('_')[0]));//using System.Linq; 

И вы можете написать список в файл на диске, как показано ниже:

using (TextWriter tw = new StreamWriter("C:\\FileNames.txt")) 
      { 
       foreach (var item in sorted) 
       { 
        tw.WriteLine(item.FileName.ToString()); 
       } 
      } 
+1

Где бы оно положило 10_a, 20_a –

+0

Nice! Вероятно, не нужно вызывать '.ToString()' в FileName ...: p –

0

Это не должно быть сложным, это то, что я делать:

  • Создать структуру Dictionary<int,List<string>>

  • От каждого имени файла выделите номер и добавьте ключ в словарь, имя файла будет добавлено в List<string>, мы используем List в случае, если имеется несколько файлов с одинаковым номером, поэтому все они будут принадлежать одному и тому же ключу. В случае, если вы можете убедиться, что номера не будет повторяться, то вы можете использовать Dictionary<int,string>

  • Сортировать Словарь на основе целочисленных ключей

Псевдо код будет как:

  • Для строки , разделите строку с помощью разделителя «_», созданная таким образом строка [] будет иметь номер в 0-м индексе, который можно преобразовать в целое и использовать в качестве ключа. На самом деле вы можете планировать использовать следующие структуры данных, которая будет внутренне сортировать ключи

SortedDictionary<int,List<string>>

+0

Дайте мне знать, если у вас есть проблема при переводе этого кода на рабочий код –

Смежные вопросы