.NET 中对以 1、10 和 2 开头的字符串进行排序并遵循数字顺序的最短方法是什么?
我需要按如下方式对文件名进行排序:1.log、2.log、10.log
但是当我使用 OrderBy(fn => fn) 时,它将对它们进行排序: 1.log, 10.log, 2.log
我显然知道这可以通过编写另一个比较器来完成,但是有没有更简单的方法可以从字典顺序更改为自然排序顺序?
编辑:目标是获得与在 Windows 资源管理器中选择“按名称排序”时相同的顺序。
I need to sort file names as follows: 1.log, 2.log, 10.log
But when I use OrderBy(fn => fn) it will sort them as:
1.log, 10.log, 2.log
I obviously know that this could be done by writing another comparer, but is there a simpler way to change from lexicographical order to natural sort order?
Edit: the objective is to obtain the same ordering as when selecting "order by name" in Windows Explorer.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(8)
您可以使用 Win32
CompareStringEx
函数。在 Windows 7 上,它支持您需要的排序。
您将使用 P/Invoke:
然后您可以创建一个使用
SORT_DIGITSASNUMBERS
标志的IComparer
:然后您可以在各种排序中使用
IComparer
API:您还可以使用 StrCmpLogicalW 这是 Windows 资源管理器使用的函数。它自 Windows XP 起就可用:
更简单,但您对比较的控制权较少。
You can use the Win32
CompareStringEx
function. On Windows 7 it supports the sorting you need.You will have use P/Invoke:
You can then create an
IComparer
that uses theSORT_DIGITSASNUMBERS
flag:You can then use the
IComparer
in various sorting API's:You can also use StrCmpLogicalW which is the function used by Windows Explorer. It has been available since Windows XP:
Simpler, but you have less control over the comparison.
如果您的文件名始终仅包含数字,则可以使用 Path.GetFileNameWithoutExtension() 放弃文件扩展名和 Convert.ToInt32() (或类似)将文件名转换为整数以进行比较:
在一般情况下,或者如果您正在寻找更“标准”的方法为此,您可以 p/invoke StrCmpLogicalW(),资源管理器用于在其视图中对文件名进行排序。但是,如果您想使用
OrderBy()
,这样做将强制您实现IComparer
。If your file names always only consist in digits, you can use Path.GetFileNameWithoutExtension() to discard the file extension and Convert.ToInt32() (or similar) to convert your file names to integers for comparison purposes:
In the general case, or if you're looking for a more "standard" way to do this, you can p/invoke StrCmpLogicalW(), which Explorer uses to sort file names in its views. However, doing that will force you to implement an
IComparer<string>
if you want to useOrderBy()
.您应该选择其中之一
You should take one of these
最简单(不一定是最快/最佳)的方法是恕我直言,将它们全部左填充到某个预定义的最大长度,并用零填充。 IE
The simplest (not necessarily fastest/optimal) way would be IMHO to left-pad them all to some predefined maximum length with zeroes. I.e.
您可以删除所有非数字字符,解析为 int,然后排序:
You could just remove all the non digit characters, parse to int and then sort:
当您可以确保名称的格式为 NUMBER.VALUE 时,您可以执行以下操作:
You can do something like this when you can assure the format of your names are NUMBER.VALUE:
不,我不这么认为 - 我想你必须自己编写它,只要你的数据只是一个字符串。
如果您将数据设置为
可以使用 LogBase-Field 进行排序的内容
no I don't think so - I guess you have to write it yourself as long as your data is just a string.
If you make your data into something like
you can sort by using the LogBase-Field
如果是按字典顺序排列就更容易了。
字符串比较始终是逐个字母的。
在不查看整个数字的情况下,您想如何处理这个问题?
不,单独的比较器是唯一的解决方案。
It would be easier if it would be a lexicographical order,.
String comparison is always letter by letter.
How you want to deal with that without looking at the whole number?
No, a separate comparer is the only solution.