C#Linq Custom Sort

Sha*_*awn 6 c# linq

我在linqtosql中有一个返回LabelNumber的查询:

var q = from list in db.Lists
        select list.LabelNumber;
Run Code Online (Sandbox Code Playgroud)

var q然后成为一个IEnumerable<string>像这样的元素:

{"1","2","2.A","2.B","3","3.A","3.B"}
Run Code Online (Sandbox Code Playgroud)

我基本上想要按照上面的顺序排序元素,但是我不能使用OrderBy(x=>x.LabelNumber)因为它"10"会在"1"之前和之后放置"2".

我假设我必须编写自定义比较器函数,但我如何使用linq执行此操作?

编辑:我认为下面的所有答案都有效,但必须在所有回复中添加一个警告.

如果您使用的是Linq2SQL,则无法在查询中使用数组索引.要解决这个问题,您应该有两个查询.一个从SQL读取的.第二个是排序:

var q = from list in db.Lists
            select list.LabelNumber;

var q2 = q.AsEnumerable()
          .OrderBy(x => int.Parse(x.LabelNumber.Split('.')[0]))
          .ThenBy(x => x.Number
                        .Contains(".") ? 
                              x.LabelNumber.Split('.')[1].ToString() 
                              : 
                              string.Empty);
Run Code Online (Sandbox Code Playgroud)

Mic*_*pat 13

OrderBy(x=>x.LabelNumber, new AlphanumComparator())
Run Code Online (Sandbox Code Playgroud)

David Koelle AlphanumComparator的优秀Alphanum自然排序算法在哪里?无需重新发明轮子.

如果您要使用C#版本,请将其更改为:

AlphanumComparator : IComparer<string>
Run Code Online (Sandbox Code Playgroud)

public int Compare(string x, string y)
Run Code Online (Sandbox Code Playgroud)

  • +1,用于向我介绍AlphanumComparator (3认同)

Jef*_*ado 9

您可能不必编写自定义比较器.如果您的所有标签都在表单中number.letter,则可以使用此标签.

var query = from list in db.Lists
            let split = list.LabelNumber.Split('.')
            let order = split.Length == 1
                ? new { a = int.Parse(split[0]), b = String.Empty }
                : new { a = int.Parse(split[0]), b = split[1] }
            orderby order.a, order.b
            select list.LabelNumber;
Run Code Online (Sandbox Code Playgroud)

如果需要更多控制,可以始终将sortby字段(ab)转换为适当的类型而不是int和字符串.


如果这是LINQ-to-SQL,则实际上这不起作用,因为这里使用的某些方法不受支持.这是一个LINQ-to-SQL友好版本.它不会产生最漂亮的查询,但它会起作用.

var query = from list in db.Lists
            let dot = list.LabelNumber.IndexOf('.')
            let name = list.LabelNumber
            let order = dot == -1
                ? new { a = Convert.ToInt32(name.Substring(0, dot)), b = String.Empty }
                : new { a = Convert.ToInt32(name.Substring(0, dot)), b = name.Substring(dot+1) }
            orderby order.a, order.b
            select list.LabelNumber;
Run Code Online (Sandbox Code Playgroud)