C#,按名称对列表中的对象进行排序

时间:2010-08-11 08:38:10

标签: c# list object short

我怎么能按名字对列表中的对象进行排序? 例如:

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

或者我可以将对象名称更改为其他内容以便更容易缩短吗?

谢谢。

6 个答案:

答案 0 :(得分: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 :(得分: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);
              });

答案 2 :(得分:0)

[检查] [1]这个问题

您需要的是具有自定义IComparer的排序功能。你现在拥有的是使用sort时的默认icomparer。这将检查字段值。

创建自定义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");
        }
}

请阅读上面的链接以获取更多信息。

答案 3 :(得分: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);

}

答案 4 :(得分: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());

    }
}

答案 5 :(得分:0)

我喜欢字符串的单行解决方案!

//Sort by Name: list = List<string>() ...
list.Sort((x, y) => String.Compare(x, y, StringComparison.Ordinal));