按版本排序字符串列表

nfp*_*lee 2 c# sorting

我有一个字符串列表.每个字符串都遵循"{Path}\UpdateTo {Version} - {Order}"模式.

我需要对列表进行排序,使得最低版本号位于顶部.如果存在多个具有相同版本号的文件,则会附加可选的订单参数.如果任何字符串上存在订单,则它应显示在具有相同版本号且没有订单号的字符串上方.

例如,给出以下列表(注意项目是随机排序的):

var files = new List<string>() {
    @"C:\Migrations\UpdateTo1.2-2",
    @"C:\Migrations\UpdateTo1.5-2",
    @"C:\Migrations\UpdateTo1.2",
    @"C:\Migrations\UpdateTo1.4",
    @"C:\Migrations\UpdateTo1.1",
    @"C:\Migrations\UpdateTo1.5",
    @"C:\Migrations\UpdateTo1.2-1",
    @"C:\Migrations\UpdateTo1.5-1"
};
Run Code Online (Sandbox Code Playgroud)

结果将是:

var files = new List<string>() {
    @"C:\Migrations\UpdateTo1.1",
    @"C:\Migrations\UpdateTo1.2-1",
    @"C:\Migrations\UpdateTo1.2-2",
    @"C:\Migrations\UpdateTo1.2",
    @"C:\Migrations\UpdateTo1.4",
    @"C:\Migrations\UpdateTo1.5-1",
    @"C:\Migrations\UpdateTo1.5-2",
    @"C:\Migrations\UpdateTo1.5"
}
Run Code Online (Sandbox Code Playgroud)

我一直在尝试各种各样的想法,但到目前为止,我的尝试已经完全混乱.如果有人可以提供帮助,我会很感激.谢谢

Aus*_*nen 5

我使用临时类来处理解析和比较以获得所需的输出.我已经包含了一些代码,可以将所有内容恢复到您的请求,但引入的"临时"类可能对路径(?)有更多的价值.

用法:

var sorted = files.Select(f => new UpdateTo(f))
    .OrderBy(u => u)
    .Select(u => u.Path)
    .ToArray();
Run Code Online (Sandbox Code Playgroud)

代码:

class UpdateTo : IComparable<UpdateTo>
{
    public decimal Version { get; private set; }
    public int Order { get; private set; }
    public string Path { get; private set; }

    private const string Prefix = "UpdateTo";

    public UpdateTo(string path)
    {
        /* No error-checking here -- BEWARE!! */
        Path = path;

        string toParse = Path.Substring(Path.IndexOf(Prefix, StringComparison.InvariantCultureIgnoreCase) + Prefix.Length);
        var split = toParse.Split('-');

        Version = decimal.Parse(split[0]);
        Order = split.Length == 2 ? int.Parse(split[1]) : int.MaxValue;
    }

    public int CompareTo(UpdateTo other)
    {
        int versionCompare = Version.CompareTo(other.Version);
        return versionCompare == 0 ? Order.CompareTo(other.Order) : versionCompare;
    }
}
Run Code Online (Sandbox Code Playgroud)

而测试......

[Test]
public void ListSort()
{
    const string first = @"C:\Migrations\UpdateTo1.1";
    const string second = @"C:\Migrations\UpdateTo1.2-1";
    const string third = @"C:\Migrations\UpdateTo1.2-2";
    const string fourth = @"C:\Migrations\UpdateTo1.2";
    const string fifth = @"C:\Migrations\UpdateTo1.4";
    const string sixth = @"C:\Migrations\UpdateTo1.5-1";
    const string seventh = @"C:\Migrations\UpdateTo1.5-2";
    const string eighth = @"C:\Migrations\UpdateTo1.5";

    var files = new List<string>{third, seventh, fourth, fifth, first, eighth, second, sixth};

    var sorted = files.Select(f => new UpdateTo(f))
        .OrderBy(u => u)
        .Select(u => u.Path)
        .ToArray();

    Assert.AreEqual(first, sorted[0]);
    Assert.AreEqual(second, sorted[1]);
    Assert.AreEqual(third, sorted[2]);
    Assert.AreEqual(fourth, sorted[3]);
    Assert.AreEqual(fifth, sorted[4]);
    Assert.AreEqual(sixth, sorted[5]);
    Assert.AreEqual(seventh, sorted[6]);
    Assert.AreEqual(eighth, sorted[7]);
}
Run Code Online (Sandbox Code Playgroud)