排序数字字符串映射字符串

本文关键字:字符串 映射 数字字符 数字 排序 | 更新日期: 2023-09-27 18:05:13

我们有一个关于字符串排序的问题。Sort在这种情况下不起作用

1-A - b 10-A 10-B 9-A 9-B…

我们真正想要的是

1-A 1-B 9-A 9-B 10-A 10-B如果我们将其作为字符串排序,结果将与第一部分类似。如果我们先解析然后排序那么我们怎么对剩下的A和B排序呢?c#有什么简单的解决方案吗?

谢谢,

排序数字字符串映射字符串

您可以在放置自定义比较逻辑的地方实现自己的比较器。然后,您可以使用此比较器实例执行排序。

我建议使用IComparer

它很容易实现,并按你想要的方式排序,例如。

1.txt
10.txt
3.txt
a10b1.txt
a1b1.txt
a2b1.txt
a2b11.txt
a2b2.txt
b1.txt
b10.txt
b2.txt  

排序

1.txt
3.txt
10.txt
a1b1.txt
a2b1.txt
a2b2.txt
a2b11.txt
a10b1.txt
b1.txt
b2.txt
b10.txt

只需使用以下代码

string[] strArr = new string[] {"1-A", "1-B", "9-A", "9-B", "10-A", "10-B"};
var q = from t in strArr select new { FirstPart =Convert.ToInt32(t.Split('-')[0]), SecondPart = t.Split('-')[1] };
string[] resArr = q.OrderBy(p => p.FirstPart).ThenBy(p => p.SecondPart).Select(p=> string.Concat(p.FirstPart, "-", p.SecondPart)) .ToArray();

一种方法是使用LINQ的OrderBy + ThenBy:

string[] strings = {"1-A", "1-B", "10-A", "10-B", "9-A", "9-B"}; 
int i = 0;
var orderedStrings = strings
   .Select(str => new { arr = str.Split('-'), str })
   .Where(x => x.arr.Length == 2 && int.TryParse(x.arr[0], out i))
   .Select(x => new { x.str, x.arr, num = int.Parse(x.arr[0])})
   .OrderBy(x => x.num)
   .ThenBy(x => x.arr[1])
   .Select(x => x.str); 

假设字符串总是由-分隔,包含两部分,并且第一部分总是intWhere确保了这一点,格式无效的字符串将被省略。

如果你想重新分配你的string[]的有序查询,你需要创建一个新的:

strings = orderedStrings.ToArray();

您正在寻找一个"自然排序顺序"。

事实证明,Windows API提供了一个StrCmpLogicalW()函数,我们可以使用p/Invoke调用它来解决这个问题。

假设您正在尝试对List<>或数组进行排序,您可以将其包装在扩展方法中,以便更容易调用:

public static class ListAndArrayExt
{
    [DllImport("shlwapi.dll", CharSet = CharSet.Unicode)]
    private static extern int StrCmpLogicalW(string lhs, string rhs);
    public static void SortNatural(this List<string> self)
    {
        self.Sort(StrCmpLogicalW);
    }
    public static void SortNatural(this string[] self)
    {
        Array.Sort(self, StrCmpLogicalW);
    }
}

您可以使用它对List<>按自然排序顺序排序。下面是一个完整的可编译控制台应用程序来演示:

using System;
using System.Collections.Generic;
using System.Runtime.InteropServices;
namespace ConsoleApp1
{
    public static class ListAndArrayExt
    {
        [DllImport("shlwapi.dll", CharSet = CharSet.Unicode)]
        private static extern int StrCmpLogicalW(string lhs, string rhs);
        public static void SortNatural(this List<string> self)
        {
            self.Sort(StrCmpLogicalW);
        }
        public static void SortNatural(this string[] self)
        {
            Array.Sort(self, StrCmpLogicalW);
        }
    }
    class Program
    {
        void run()
        {
            var strings = new List<string>
            {
                "1-A",
                "1-B",
                "10-A",
                "10-B",
                "9-A",
                "9-B"
            };
            strings.SortNatural();
            foreach (var s in strings)
                Console.WriteLine(s);
        }
        static void Main()
        {
            new Program().run();
        }
    }
}

输出如下所示的字符串:

1-A
1-B
9-A
9-B
10-A
10-B

您需要实现自定义比较器,它将按照您的喜好比较字符串。例如NaturalComparer

尝试使用

ArrayList

则使用

ArrayList.Sort ();

将对数组进行排序。