如何按数字样式对字符串数组进行排序?

时间:2022-10-30 16:02:17

I have a filenames array, I want to sort it by numeric style, please give to me a solution.

我有一个文件名数组,我想按数字样式排序,请给我一个解决方案。

Example1:

Original array: [name99.txt, name98.txt, name100.txt]
Sorted array: [name98.txt, name99.txt, name100.txt]
(Using string sorting, result of sorting is [name100.txt, name98.txt, name99.txt])

原始数组:[name99.txt,name98.txt,name100.txt]排序数组:[name98.txt,name99.txt,name100.txt](使用字符串排序,排序结果为[name100.txt,name98.txt, name99.txt])

Example2:

Original array: [a99.txt, b98.txt, b100.txt]
Sorted array: [a99.txt, b98.txt, b100.txt]
(Using string sorting, result of sorting is [a99.txt, b100.txt, b99.txt])

原始数组:[a99.txt,b98.txt,b100.txt]排序数组:[a99.txt,b98.txt,b100.txt](使用字符串排序,排序结果为[a99.txt,b100.txt, b99.txt])

3 个解决方案

#1


8  

string[] ar = new string[] { "name99.txt", "name98.txt", "name100.txt" };
Array.Sort(ar, (a, b) => int.Parse(Regex.Replace(a, "[^0-9]", "")) - int.Parse(Regex.Replace(b, "[^0-9]", "")));

foreach (var a in ar)
    Console.WriteLine(a);

The above assumed that your files are allways called name###.txt. For the real numeric sorting use the following more complicated version:

以上假设您的文件总是名为###。txt。对于真正的数字排序,请使用以下更复杂的版本:

public static void NumericalSort(string[] ar)
{
    Regex rgx = new Regex("([^0-9]*)([0-9]+)");
    Array.Sort(ar, (a, b) =>
    {
        var ma = rgx.Matches(a);
        var mb = rgx.Matches(b);
        for (int i = 0; i < ma.Count; ++i)
        {
            int ret = ma[i].Groups[1].Value.CompareTo(mb[i].Groups[1].Value);
            if (ret != 0)
                return ret;

            ret = int.Parse(ma[i].Groups[2].Value) - int.Parse(mb[i].Groups[2].Value);
            if (ret != 0)
                return ret;
        }

        return 0;
    });
}

static void Main(string[] args)
{
    string[] ar = new string[] { "a99.txt", "b98.txt", "b100.txt" };

    NumericalSort(ar);

    foreach (var a in ar)
        Console.WriteLine(a);
}

#2


4  

There may well be a managed way to do this, but I would probably just P/invoke to StrCmpLogicalW.

可能有一种托管方式可以做到这一点,但我可能只是P /调用StrCmpLogicalW。

[DllImport("shlwapi.dll", CharSet=CharSet.Unicode, ExactSpelling=true)]
static extern int StrCmpLogicalW(String x, String y);    

If you use this function, rather than rolling your own comparison function, you'll get the same behaviour as Explorer and other system components that use logical comparison.

如果您使用此函数,而不是滚动自己的比较函数,您将获得与Explorer和使用逻辑比较的其他系统组件相同的行为。

Note, however, that this will not work in environments where WinAPI is inaccessible (such as Windows Phone, Mono or Silverlight), might work differently on different systems and should be decorated with a comment so the future maintainer of your code knows why P/Invoke is used for sorting.

但请注意,这在WinAPI无法访问的环境(如Windows Phone,Mono或Silverlight)中不起作用,可能在不同系统上的工作方式不同,应该用注释进行修饰,以便代码的未来维护者知道为什么P / Invoke用于排序。

#3


1  

One solution can be found here: Alphanumeric Sorting

可在此处找到一种解决方案:字母数字排序

#1


8  

string[] ar = new string[] { "name99.txt", "name98.txt", "name100.txt" };
Array.Sort(ar, (a, b) => int.Parse(Regex.Replace(a, "[^0-9]", "")) - int.Parse(Regex.Replace(b, "[^0-9]", "")));

foreach (var a in ar)
    Console.WriteLine(a);

The above assumed that your files are allways called name###.txt. For the real numeric sorting use the following more complicated version:

以上假设您的文件总是名为###。txt。对于真正的数字排序,请使用以下更复杂的版本:

public static void NumericalSort(string[] ar)
{
    Regex rgx = new Regex("([^0-9]*)([0-9]+)");
    Array.Sort(ar, (a, b) =>
    {
        var ma = rgx.Matches(a);
        var mb = rgx.Matches(b);
        for (int i = 0; i < ma.Count; ++i)
        {
            int ret = ma[i].Groups[1].Value.CompareTo(mb[i].Groups[1].Value);
            if (ret != 0)
                return ret;

            ret = int.Parse(ma[i].Groups[2].Value) - int.Parse(mb[i].Groups[2].Value);
            if (ret != 0)
                return ret;
        }

        return 0;
    });
}

static void Main(string[] args)
{
    string[] ar = new string[] { "a99.txt", "b98.txt", "b100.txt" };

    NumericalSort(ar);

    foreach (var a in ar)
        Console.WriteLine(a);
}

#2


4  

There may well be a managed way to do this, but I would probably just P/invoke to StrCmpLogicalW.

可能有一种托管方式可以做到这一点,但我可能只是P /调用StrCmpLogicalW。

[DllImport("shlwapi.dll", CharSet=CharSet.Unicode, ExactSpelling=true)]
static extern int StrCmpLogicalW(String x, String y);    

If you use this function, rather than rolling your own comparison function, you'll get the same behaviour as Explorer and other system components that use logical comparison.

如果您使用此函数,而不是滚动自己的比较函数,您将获得与Explorer和使用逻辑比较的其他系统组件相同的行为。

Note, however, that this will not work in environments where WinAPI is inaccessible (such as Windows Phone, Mono or Silverlight), might work differently on different systems and should be decorated with a comment so the future maintainer of your code knows why P/Invoke is used for sorting.

但请注意,这在WinAPI无法访问的环境(如Windows Phone,Mono或Silverlight)中不起作用,可能在不同系统上的工作方式不同,应该用注释进行修饰,以便代码的未来维护者知道为什么P / Invoke用于排序。

#3


1  

One solution can be found here: Alphanumeric Sorting

可在此处找到一种解决方案:字母数字排序