如何对列表<string> / 字符串版本号数组进行排序?
Posted
技术标签:
【中文标题】如何对列表<string> / 字符串版本号数组进行排序?【英文标题】:How to sort a list<string> / array of string version number? 【发布时间】:2016-10-01 12:57:21 【问题描述】:我有一个版本字符串列表(见图),我想按降序对它们进行排序。
我见过一些使用 Version 类来比较它们的解决方案,但我想不出任何解决方案可以像这样对整个列表进行排序。实现这一目标的最简单的方法是什么?
【问题讨论】:
List<Version>
是最简单的。包含数字的字符串不会对列表数字进行排序。或者,查找/使用自然排序
旁注:请不要在您的帖子中添加“谢谢”和“搜索了很多”文本。为了展示研究成果,请提供您尝试过的方法的链接,并简要说明为什么它没有解决您的问题。
【参考方案1】:
这个简单的实现有什么问题?
using System;
using System.Collections.Generic;
namespace ConsoleApplication1
class Program
static void Main(string[] args)
var ver = new List<Version>();
ver.Add(new Version("3.5"));
ver.Add(new Version("3.15"));
ver.Add(new Version("3.10"));
ver.Add(new Version("3.1"));
ver.Sort();
ver.Reverse();
【讨论】:
没想到。当我阅读 Version 类时,我认为我只需要在 2 个对象之间进行比较【参考方案2】:你可以使用 IComparable
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace ConsoleApplication2
class Program
static void Main(string[] args)
List<string> data = new List<string>
"3.5.0.1", "3.4.1.9", "3.4.1.56", "3.4.1.55", "3.4.1.46",
"3.4.1.45", "3.4.1.44", "3.4.1.30", "3.4.1.3", "3.4.1.22",
"3.4.1.2", "3.4.1.11", "3.4.1.0", "3.4.0.7", "3.4.0.3",
"3.4.0.1", "3.3.0.8", "3.3.0.4", "3.3.0.0", "3.2.0.9",
"3.2.0.6", "3.2.0.3", "3.2.0.27", "3.2.0.20", "3.2.0.15",
"3.2.0.1", "3.2.0.0", "3.1.0.7", "3.1.0.15", "3.1.0.14"
;
List<SortPara> sortPara = data.Select(x => new SortPara(x)).ToList();
data = sortPara.OrderBy(x => x).Select(x => x.strNumbers).ToList();
data = sortPara.OrderByDescending(x => x).Select(x => x.strNumbers).ToList();
public class SortPara : IComparable<SortPara>
public List<int> numbers get; set;
public string strNumbers get; set;
public SortPara(string strNumbers)
this.strNumbers = strNumbers;
numbers = strNumbers.Split(new char[] '.' ).Select(x => int.Parse(x)).ToList();
public int CompareTo(SortPara other)
int shortest = this.numbers.Count < other.numbers.Count ? this.numbers.Count : other.numbers.Count;
int results = 0;
for (int i = 0; i < shortest; i++)
if (this.numbers[i] != other.numbers[i])
results = this.numbers[i].CompareTo(other.numbers[i]);
break;
return results;
【讨论】:
我认为这样的事情太过分了 只因为有版本方法。这是如何使用 CompareTo() 方法创建自定义 IComparable 方法的一个很好的示例。 @JackLe 这实际上是一个矫枉过正的唯一原因是这些方法已经存在于最新的 C# 库中,但是您可能会发现此代码 sn-p 非常有用,因为您需要将object x
与 @ 进行比较987654323@ 必须实现一个自定义的IComparable
接口。【参考方案3】:
您应该使用IComparable
作为 jdweng,只需稍作编辑即可比较“2.1.0.4”和“2.1”等版本:
public int CompareTo(SortPara other)
int shortest = this.numbers.Count < other.numbers.Count ? this.numbers.Count : other.numbers.Count;
int results = 0;
for (int i = 0; i < shortest; i++)
if (this.numbers[i] != other.numbers[i])
results = this.numbers[i].CompareTo(other.numbers[i]);
break;
if (results != 0)
return results;
if (this.numbers.Count > other.numbers.Count)
return 1;
else if (this.numbers.Count < other.numbers.Count)
return -1;
else
return 0;
【讨论】:
您可以通过返回两个计数来省略最后的所有 if-else:return this.numbers.Count - other.numbers.Count;。如果在 for 循环中返回,则可以删除变量 results 和 break。计算最短使用 Math.Min(this.numbers.Count, other.numbers.Count);【参考方案4】:这是对语义版本控制 (https://semver.org) 进行排序的解决方案。 Nuget.Core 提供了一个 SemanticVersion 类,其运行方式与 .net 中的标准 Version 类非常相似。它会将您的字符串解析为 IComparable 和 IEquatable 对象,以便您可以比较多个版本或在集合中对它们进行排序等。
Nuget.Core:https://www.nuget.org/packages/nuget.core/(你可以通过 nuget 拉取这个库)
https://github.com/NuGet/NuGet2/blob/2.13/src/Core/SemanticVersion.cs
var rawVersions = new [] "v1.4.0", "v1.4.0-patch10", "v1.4.0-patch2";
var versions = rawVersions.Select(v => new SemanticVersion(v));
var sorted = versions.ToList().Sort();
【讨论】:
以上是关于如何对列表<string> / 字符串版本号数组进行排序?的主要内容,如果未能解决你的问题,请参考以下文章
如何根据特定索引范围对 ArrayList<String> 进行排序
如何使用许多字符串值初始化字符串列表 (List<string>)