2010-08-11 2 views
1

как я могу сортировать объекты в списке по их названию? Пример:C#, сортировка объектов в списке по имени

mapPart_1_0 
mapPart_1_2 
mapPart_1_4 
mapPart_1_6 
mapPart_1_8 
mapPart_1_10 
mapPart_1_12 
mapPart_1_24 
mapPart_2_1 
mapPart_2_11 
Big list continues... (somewhere in that list are missing that aper in sorted one) 

В:

mapPart_1_0 
mapPart_1_1 
mapPart_1_2 
mapPart_1_3 
mapPart_1_4 
mapPart_1_5 
... 
mapPart_2_1 
mapPart_2_2 
mapPart_2_3 
... 
mapPart_2_11 
... 

Или может я изменить имя объекта на что-то другое, поэтому было бы проще коротка?

спасибо.

+2

Второй список не похож на первый отсортированный список.Например, во втором списке содержится элемент «mapPart_1_5», который не входит в первый список. Просьба уточнить, например. имея все элементы в обоих списках, один из которых не сортирован, сортируется. Я не уверен, что этот вопрос достаточно ясен для хорошего ответа. – Manfred

+0

Непонятно, что вы хотите изменить. ваш первый пример сортируется по имени в натуральном порядке (т. е. 2 до 10), и невозможно определить из второго примера, если это один (естественный или строгий сорт даст тот же результат). вы, кажется, просто удалили несколько объектов ...? –

ответ

0

Это включает в себя некоторые либеральные предположения о ваших требованиях, и это быстрый хак, но. ..

var groups = myList.Select (text => 
new 
{ 
    FirstNum = int.Parse(text.Split('_')[1]), 
    SecondNum = int.Parse(text.Split('_')[2]) 
}) 
.GroupBy(a => a.FirstNum, a => a.SecondNum); 


foreach(var group in groups.OrderBy(g => g.Key)) 
{ 
    int min = group.Min(); 
    int max = group.Max(); 

    for(int i=min; i<=max; i++) 
    yield return string.Format ("mapPart_{0}_{1}", group.key, i); 

} 
+0

Спасибо! Это помогло мне выделить. – Semas

+0

Нет проблем. Конечно, есть люди, которые могли бы дать лучшие ответы, хотя бы, если бы вы могли быть более ясными в заявлении о проблеме. – Ani

0

[Проверить] [1] этот вопрос

то, что вам нужно, это функция сортировки с пользовательской IComparer. Теперь вы используете icomparer по умолчанию при использовании сортировки. это проверит значение поля.

При создании пользовательского IComparer (вы делаете это в своем классе, реализуя интерфейс Icomparable). что он делает: ваш объект проверяет себя на каждый другой объект в отсортированном вами списке.

это делается функцией. (Не волнуйтесь, VS будет implementd, когда ссылается вашего интерфейс

public class ThisObjectCLass : IComparable{ 

    public int CompareTo(object obj) { 
      ThisObjectCLass something = obj as ThisObjectCLass ; 
      if (something!= null) 
       if(this.key.Split("_")[1].CompareTo(object.key.Split("_")[1]) == 0){ 
       // extratc the numbers from your name and compare the numbers, you have   to add some logic but I assume you know something about c# 
       //then: 
        if ..... 
       } 
       else if(this.key.Split("_")[1] "is more important then(use some logic here)" object.key.Split("_")[1]){ 
       return 1 
       } 
       else return -1 
      else 
       throw new ArgumentException("I am a dumb little rabid, trying to compare different base classes"); 
     } 
} 

читать по ссылкам выше для более полной информации.

1

Вы могли бы хотеть рассмотреть natural sort

Обычный вид:.

  • mapPart_1_1
  • mapPart_1_10
  • mapPart_1_2

Естественный сорт:

  • mapPart_1_1
  • mapPart_1_2
  • mapPart_1_10

Вы можете прочитать Natural Sorting in C#.

1

Я думаю, что вы могли бы сделать что-то вроде этого (не проверено)

var yourList= new List<YourObject>(); 
//add items to your list 

yourList.Sort(delegate(YourObject p1, YourObject p2) 
       { 
        //you can make this delegate more complex if you need it 
        return p1.Name.CompareTo(p2.Name); 
       }); 
0

Похоже, это может быть то, что вы хотите, если вы хотите, чтобы сортировка подчиняться каждый маркер? Честно говоря, я не уверен, что вы хотите, чтобы ваши результаты были ...

class Program 
{ 
    public class ObjectNameComparer : IComparer<object> 
    { 
     public int Compare(object x, object y) 
     { 
      var n1 = x.ToString().Split('_'); 
      var n2 = y.ToString().Split('_'); 
      var nameCompare = string.Compare(n1[0], n2[0], StringComparison.OrdinalIgnoreCase); 
      if (nameCompare == 0) 
      { 
       var i1 = int.Parse(n1[1]); 
       var i2 = int.Parse(n2[1]); 
       if (i1 == i2) 
       { 
        var i12 = int.Parse(n1[2]); 
        var i22 = int.Parse(n2[2]); 
        return i12 - i22; 
       } 
       return i1 - i2; 
      } 
      return nameCompare; 
     } 
    } 

    static void Main(string[] args) 
    { 
     var objectList = new List<object>(); 

     objectList.AddRange(new object[] 
      { 
       "mapPart_1_0", 
       "mapPart_1_10", 
       "mapPart_100_10", 
       "mapPart_1_12", 
       "mapPart_22_11", 
       "mapPart_1_24", 
       "mapPart_2_1", 
       "mapPart_10_24", 
       "mapPart_2_11", 
      }); 

     var ordered = objectList.OrderBy(a => a, new ObjectNameComparer()); 

    } 
} 
0

Однострочное решение, которое я предпочитаю для строки!

//Sort by Name: list = List<string>() ... 
list.Sort((x, y) => String.Compare(x, y, StringComparison.Ordinal)); 
Смежные вопросы