如何在c#中按降序排列版本列表
本文关键字:降序 排列 版本 列表 | 更新日期: 2023-09-27 18:29:09
我有一个列表,其中包含一些版本。
样本数据:
"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
应该是一个例外,并且应该作为数字工作(从版本的角度来看,强硬的2.2.1或任何具有多个小数的数字a都是无效的,我希望它们有条件地有效。
预期结果:"NA" , "7.5.3" , "7.5" , "4.5" ,"2.3.4.5" ,"2.2.1" , "2.1"
您可以使用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);
所以实际上,在类中存储版本而不是字符串会更好。
在LINQ查询中使用此扩展比使用局部变量更好。
就像@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);
}
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);
}
}
}