C #, сортировка объектов в списке по имени - PullRequest
1 голос
/ 11 августа 2010

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

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)

Into:

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

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

Спасибо.

Ответы [ 6 ]

1 голос
/ 11 августа 2010

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

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);
              });
1 голос
/ 11 августа 2010

Возможно, вы захотите рассмотреть естественную сортировку .

Обычный сорт:

  • mapPart_1_1
  • mapPart_1_10
  • mapPart_1_2

Натуральный сорт:

  • mapPart_1_1
  • mapPart_1_2
  • mapPart_1_10

Вы могли бы прочитать Естественная сортировка в C # .

0 голосов
/ 13 декабря 2013

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

//Sort by Name: list = List<string>() ...
list.Sort((x, y) => String.Compare(x, y, StringComparison.Ordinal));
0 голосов
/ 11 августа 2010

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

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 голосов
/ 11 августа 2010

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

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 голосов
/ 11 августа 2010

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

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

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

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

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

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

...