C# 如何根据整型值和字符值对自定义列表进行排序

C# 如何根据整型值和字符值对自定义列表进行排序,c#,list,sorting,C#,List,Sorting,我有一个自定义对象列表,列表中的一个属性是一个字符串,它可以包含整数或整数,然后是一个字符。像这样: 1, 1A, 2, 3, 4, 4B, 4A 如何对列表进行排序,使其按此排序 1, 1A, 2, 3, 4, 4A, 4B 我已经检查了以下链接。。。但它只处理字符串数组,我的是一个具有多个属性的列表对象 这是我的自定义对象列表 var myList = new List<Article> { new Article {Position = "1", Info = "t

我有一个自定义对象列表,列表中的一个属性是一个字符串,它可以包含整数或整数,然后是一个字符。像这样:

1, 1A, 2, 3, 4, 4B, 4A
如何对列表进行排序,使其按此排序

1, 1A, 2, 3, 4, 4A, 4B
我已经检查了以下链接。。。但它只处理字符串数组,我的是一个具有多个属性的列表对象

这是我的自定义对象列表

var myList = new List<Article>
{
    new Article {Position = "1", Info = "test1"},
    new Article {Position = "2", Info = "test2"},
    new Article {Position = "3", Info = "test3"},
    new Article {Position = "4", Info = "test4"},
    new Article {Position = "4B", Info = "test5"},
    new Article {Position = "4A", Info = "test6"}
};
var myList=新列表
{
新文章{Position=“1”,Info=“test1”},
新文章{Position=“2”,Info=“test2”},
新文章{Position=“3”,Info=“test3”},
新文章{Position=“4”,Info=“test4”},
新文章{Position=“4B”,Info=“test5”},
新文章{Position=“4A”,Info=“test6”}
};

我正在使用由实现的自定义
IComparer
(如果这有帮助,请确保给他积分),并添加缺少的部分,这只是为了使用可枚举的
重载。OrderBy
接受自定义
IComparer

void Main()
{

var myList=new List

我正在使用由实现的自定义<代码>IComparer
(如果这有帮助,请确保给他积分),并添加缺少的部分,这只是为了使用<代码>枚举的重载。OrderBy接受自定义<代码>IComparer:

void Main()
{

var myList=new List

首先,我们可以使用Windows API方法定义“自然排序”的列表扩展:


注意:本例不需要使用
public static void sort natural(此列表本身)
方法,但为了完整起见,我将其包括在内。

首先,我们可以使用Windows API方法定义“自然排序”的列表扩展:


注意:本例不需要使用
public static void sort natural(此列表本身)
方法,但为了完整起见,我将其包括在内。

为了简单起见,您可以将Regex与Linq结合使用:

Regex rgxNumber = new Regex(@"\d+");
Regex rgxCharacters = new Regex("[a-zA-Z]+");

Func<string, int> getNumberPart = str => int.Parse(rgxNumber.Match(str).ToString());
Func<string, string> getCharactersPart = str => rgxCharacters.Match(str).ToString();

var orderd = myList.OrderBy(x => getNumberPart(x.Position))
                   .ThenBy(x => getCharactersPart(x.Position)).ToList();
Regex rgxNumber=newregex(@“\d+”);
正则表达式rgxCharacters=新正则表达式(“[a-zA-Z]+”);
Func getNumberPart=str=>int.Parse(rgxNumber.Match(str.ToString());
Func getCharactersPart=str=>rgxCharacters.Match(str).ToString();
var orderd=myList.OrderBy(x=>getNumberPart(x.Position))
.ThenBy(x=>getCharactersPart(x.Position)).ToList();

这假设不存在格式为
1B2
的数据。

为简单起见,您可以将Regex与Linq结合使用:

Regex rgxNumber = new Regex(@"\d+");
Regex rgxCharacters = new Regex("[a-zA-Z]+");

Func<string, int> getNumberPart = str => int.Parse(rgxNumber.Match(str).ToString());
Func<string, string> getCharactersPart = str => rgxCharacters.Match(str).ToString();

var orderd = myList.OrderBy(x => getNumberPart(x.Position))
                   .ThenBy(x => getCharactersPart(x.Position)).ToList();
Regex rgxNumber=newregex(@“\d+”);
正则表达式rgxCharacters=新正则表达式(“[a-zA-Z]+”);
Func getNumberPart=str=>int.Parse(rgxNumber.Match(str.ToString());
Func getCharactersPart=str=>rgxCharacters.Match(str).ToString();
var orderd=myList.OrderBy(x=>getNumberPart(x.Position))
.ThenBy(x=>getCharactersPart(x.Position)).ToList();

这假设不存在形式为
1B2
的数据。

我假设您需要就地排序?您是否尝试使用var orderdlist=myList.Orderby(x=>x.Position)我假设您需要就地排序?您是否尝试使用var orderdlist=myList.Orderby(x=>x.Position)请注意,
OrderBy
创建了一个新的序列,您不需要将它赋回任何变量。@MatthewWatson不确定为什么创建自定义比较器很复杂?我认为您的答案肯定会更有效,执行就地排序,但我不确定我会称之为简单。@MatthewWatson我认为我的解决方案是最简单的比较器它实际上只有一行实际代码:
self.Sort((lhs,rhs)=>StrCmpLogicalW(stringSelector(lhs),stringSelector(rhs)))
@MatthewWatson是的,但它有一个隐藏的假设,即OP熟悉PInvoke,这一点我不确定。请注意,
OrderBy
创建了一个新的序列,您不会将其分配回任何变量。@MatthewWatson不确定为什么创建自定义比较器会很复杂?我想您的答案肯定会更好rmant one,正在进行就地排序,但我不确定我会称之为简单。@MatthewWatson我认为我的解决方案与其他两个方案相比是最简单的。它很简单,因为它实际上只有一行实际代码:
self.sort((lhs,rhs)=>StrCmpLogicalW(stringSelector(lhs),stringSelector(rhs)))
@MatthewWatson是的,但它有一个隐藏的假设,即OP对PInvoke很熟悉,我不确定是否如此。
myList.SortNatural(x => x.Position);
Regex rgxNumber = new Regex(@"\d+");
Regex rgxCharacters = new Regex("[a-zA-Z]+");

Func<string, int> getNumberPart = str => int.Parse(rgxNumber.Match(str).ToString());
Func<string, string> getCharactersPart = str => rgxCharacters.Match(str).ToString();

var orderd = myList.OrderBy(x => getNumberPart(x.Position))
                   .ThenBy(x => getCharactersPart(x.Position)).ToList();