如何通过c#中的降序版本列表进行排序?

时间:2016-01-05 10:26:24

标签: c# .net linq

我的列表中有一些版本。

示例数据:

"4.5","2.1","2.2.1","7.5","7.5.3","N/A","2.3.4.5"

正如您可以看到的数据一样,我试图通过降序难度3.8.5来排序列表invalid数字& NA是无效的。

代码:

decimal result;
var sortedVData = vData.OrderByDescending(v => decimal.TryParse(v.vCode, out result) ? Convert.ToDecimal(v.vCode) : decimal.MaxValue);

输出: "NA" , "7.5.3" , '2.3.4.5' , "2.2.1" , '7.5' , '4.5' , '2.1'

正如您在其他(:)条件中所看到的那样,如果存在无效值(任何带有文字的字符串),decimal.MaxValue会使NA成为顶部但2.2.1 1}}应该是一个例外,并且应该作为数字(艰难的2.2.1或任何具有多个小数的数字a在版本的观点中是无效的,我希望它们在条件上有效。

预期结果: "NA" , "7.5.3" , "7.5" , "4.5" ,"2.3.4.5" ,"2.2.1" , "2.1"

3 个答案:

答案 0 :(得分:3)

您可以使用Version.TryParse和此扩展方法进行LINQ查询:

public static Version TryGetVersion(this string item)
{
    Version ver;
    bool success = Version.TryParse(item, out ver);
    if (success) return ver;
    return null;
}

然后完整的查询很简单:

var sortedVData = vData
    .Select(v => new { Obj = v, Version = v.vCode.TryGetVersion() })
    .OrderBy(x => x.Version != null)    // first all invalid versions
    .ThenByDescending(x => x.Version)   // then by version descending
    .Select(x => x.Obj);

所以实际上最好在你的班级中存储versions而不是字符串。

better to use this extension in LINQ queries比使用本地变量。

答案 1 :(得分:1)

就像@WaiHaLee所说,你可以使用Version,它实现了IComparable,所以你可以这样做:

static void Main(string[] args)
    {
        var data = new[] {"4.5","2.1","2.2.1","7.5","7.5.3",@"N/A","2.3.4.5"};
        foreach(var v in data.OrderByDescending(OrderVersion))
            Console.WriteLine(v);
    }

    private static IComparable OrderVersion(string arg)
    {
        //Treat N/A as highest version
        if (arg == "N/A")
            return new Version(Int32.MaxValue,Int32.MaxValue); 
        return Version.Parse(arg);
    }

答案 2 :(得分:1)

public class VersionsComparer: IComparer<string>
{
    public int Compare(string x, string y)
    {

        if (x.ToLower() == @"n/a")
        {
            if (y.ToLower() == @"n/a")
                return 0;

            return -1;
        }

        if (y.ToLower() == @"n/a")
        {
            if (x.ToLower() == @"n/a")
                return 0;

            return 1;
        }

        var verX = Version.Parse(x);
        var verY = Version.Parse(y);

        return verX.CompareTo(verY);
    }
}

class Program
{
    static void Main(string[] args)
    {
        var versions = new[] { "4.5", "2.1", "2.2.1", "7.5", "7.5.3", @"N/A", "2.3.4.5" };


        foreach (var v in versions.OrderByDescending(v => v, new VersionsComparer()))
        {
            Console.WriteLine(v);
        }
    }


}