我有很多在这号码列表。 但由于一些额外的字母,它们被保存为字符串。
我的名单看起来是这样的:
1
10
11
11a
11b
12
2
20
21a
21c
A1
A2
...
,但它应该是这样的
1
2
10
11a
11b
...
A1
A2
...
我怎么排序我的名单得到这样的结果?
我有很多在这号码列表。 但由于一些额外的字母,它们被保存为字符串。
我的名单看起来是这样的:
1
10
11
11a
11b
12
2
20
21a
21c
A1
A2
...
,但它应该是这样的
1
2
10
11a
11b
...
A1
A2
...
我怎么排序我的名单得到这样的结果?
由先前的评论去,我还要实现一个自定义IComparer<T>
类。从我能收集到的信息来看,这些项目的结构可以是一个数字,也可以是一个数字和一个字母组合。如果是这种情况,则应执行以下IComparer<T>
实施。
public class CustomComparer : IComparer<string>
{
public int Compare(string x, string y)
{
var regex = new Regex("^(d+)");
// run the regex on both strings
var xRegexResult = regex.Match(x);
var yRegexResult = regex.Match(y);
// check if they are both numbers
if (xRegexResult.Success && yRegexResult.Success)
{
return int.Parse(xRegexResult.Groups[1].Value).CompareTo(int.Parse(yRegexResult.Groups[1].Value));
}
// otherwise return as string comparison
return x.CompareTo(y);
}
}
有了这个IComparer<T>
,你就可以做
var myComparer = new CustomComparer();
myListOfStrings.Sort(myComparer);
这已经过测试与下列项目进行排序您的string
列表:
2, 1, 4d, 4e, 4c, 4a, 4b, A1, 20, B2, A2, a3, 5, 6, 4f, 1a
和给出结果:
1, 1a, 2, 20, 4a, 4b, 4c, 4d, 4e, 4f, 5, 6, A1, A2, a3, B2
那么,你需要从每个字符串中提取数字,然后根据数字列表中的键列表对字符串列表进行排序。分两步做。
要从每个字符串中提取数字,我认为最简单的方法是使用正则表达式 - 查找(\d+)
的匹配项(如果您有负数或十进制数,则必须使用不同的正则表达式) 。比方说,你这样做,在一个函数调用ExtractNumber
现在你可以使用一些有创意的LINQ排序,像这样:
strings.Select(s=>new { key=ExtractNumber(s), value=s }) // Create a key-value pair
.OrderBy(p=>p.key) // Sort by key
.Select(p=>p.Value); // Extract the values
这看起来像是一个使用LINQ的优雅解决方案,但当迭代到达项目'A1'和'A2'时会发生什么? – Richard 2012-04-03 08:11:34
int.Parse((new regex(@“(?<= pdf _)\ d *?(?= _ \ .bmp $)”))。Match(file).Value); // matches pdf_123456890_.bmp – 2017-02-09 18:29:00
我是相当新的C#,但这里是一个解决方案,我在欣赏Java:您需要分两步进行操作,首先定义一个自定义的IComparer,然后在调用sort方法时使用它。所以,你应该能够做这样的事情:
public class MyListSorter : IComparer<MyObject>
{
public int Compare(MyObject obj1, MyObject obj2)
{
if (!Char.IsNumber(obj1) && Char.IsNumber(obj2))
{
return 0;
}
else if (Char.IsNumber(obj1) && !Char.IsNumber(obj2))
{
return 1;
}
else
{
return obj2.CompareTo(obj1);
}
}
}
,然后IComparer的
myObjectList.Sort(new MyListSorter());
由于这包括许多字符串操作,正则表达式等,我不认为这是一个有效的算法,但它似乎工作。
List<string> list1 = new List<string>() { "11c22", "1", "10", "11", "11a", "11b", "12", "2", "20", "21a", "21c", "A1", "A2" };
List<string> list2 = new List<string>() { "File (5).txt", "File (1).txt", "File (10).txt", "File (100).txt", "File (2).txt" };
var sortedList1 = NaturalSort(list1).ToArray();
var sortedList2 = NaturalSort(list2).ToArray();
public static IEnumerable<string> NaturalSort(IEnumerable<string> list)
{
int maxLen = list.Select(s => s.Length).Max();
Func<string, char> PaddingChar = s => char.IsDigit(s[0]) ? ' ' : char.MaxValue;
return list
.Select(s =>
new
{
OrgStr = s,
SortStr = Regex.Replace(s, @"(\d+)|(\D+)", m => m.Value.PadLeft(maxLen, PaddingChar(m.Value)))
})
.OrderBy(x => x.SortStr)
.Select(x => x.OrgStr);
}
很想看到一个版本,它实际上处理版本号...有多个数字,以保持秩序:2.5.7,10.3.2,2.18.3等 – pmbAustin 2016-07-19 21:09:47
这个作品太棒了!谢谢! – 2016-10-24 08:14:11
打破 '数量' 为组件,然后排序由。 – leppie 2012-04-03 07:34:22
是的,自然排序是你之后的东西。这是Jon所说的重复。在http://zootfroot.blogspot.com.au/2009/09/natural-sort-compare-with-linq-orderby.html – 2012-04-03 07:38:52
[C#中的自然分类](http://www.interact -sw.co.uk/iangblog/2007/12/13/natural-sorting) – 2012-04-03 08:13:10