C# / 对文本文件进行排序 / IComparer / 自定义排序
C# / Sorting a text file / IComparer / Custom sort
我有一个文本文件需要排序。
每一行都有一个包名、一个管道和一个版本号。
示例:
- 自动夹具|4.15.0
- Castle.Windsor.Lifestyles|0.3.0
我尝试使用默认的 list.Sort() 方法,但我得到了:
AutoFixture|4.15.0
Castle.Core|3.3.0
Castle.Windsor.Lifestyles|0.3.0
Castle.Windsor|3.3.0
FluentAssertions|5.10.3
而不是
AutoFixture|4.15.0
Castle.Core|3.3.0
Castle.Windsor|3.3.0
Castle.Windsor.Lifestyles|0.3.0
FluentAssertions|5.10.3
如图所示,我希望“Castle.Windsor”出现在“Castle.Windsor.Lifestyles”之前。
我很确定我必须使用 IComparer,但我找不到先获取较短名称的方法。
到目前为止,我创建了一个像这样的自定义排序,但它不起作用..
public class PackageComparer : IComparer<string>
{
// Assume that each line has the format: name|number
private readonly Regex packageRegEx = new Regex(@"[\w.]+\|[\d.]+", RegexOptions.Compiled);
public int Compare(string x, string y)
{
var firstPackage = this.packageRegEx.Match(x);
var firstLeft = firstPackage.Groups[1].Value;
var firstRight = firstPackage.Groups[2].Value;
var secondPackage = this.packageRegEx.Match(y);
var secondLeft = secondPackage.Groups[1].Value;
var secondRight = secondPackage.Groups[2].Value;
if (firstLeft < secondLeft)
{
return -1;
}
if (firstRight > secondLeft)
{
return 1;
}
return string.CompareOrdinal(firstSceneAlpha, secondSceneAlpha);
}
}
好吧,您可以使用 Linq,按管道拆分并按包名称排序,然后按版本控制:
var input = @"AutoFixture|4.15.0
Castle.Core|3.3.0
Castle.Windsor.Lifestyles|0.3.0
Castle.Windsor|3.3.0
FluentAssertions|5.10.3
Castle.Core|3.1.0";
var list = input.Split(new string[]{"\r\n","\n"},StringSplitOptions.None).ToList();
list = list
.OrderBy(x => x.Split('|')[0])
.ThenBy(x => new Version(x.Split('|')[1]))
.ToList();
输出:
AutoFixture|4.15.0
Castle.Core|3.1.0
Castle.Core|3.3.0
Castle.Windsor|3.3.0
Castle.Windsor.Lifestyles|0.3.0
FluentAssertions|5.10.3
你可以这样做:
public class YourClassName
{
public string PackageName { get; set; }
public string Pipe { get; set; }
public string Version { get; set; }
}
将您的数据加载到列表中进行排序
List<YourClassName> list = souce of data;
list = SortList<YourClassName>(list, "PackageName");
排序列表方法:
public List<YourClassName> SortList<TKey>(List<YourClassName> list, string sortBy)
{
PropertyInfo property = list.GetType().GetGenericArguments()[0].GetProperty(sortBy);
return list.OrderBy(e => property.GetValue(e, null)).ToList<YourClassName>();
}
我有一个文本文件需要排序。
每一行都有一个包名、一个管道和一个版本号。
示例:
- 自动夹具|4.15.0
- Castle.Windsor.Lifestyles|0.3.0
我尝试使用默认的 list.Sort() 方法,但我得到了:
AutoFixture|4.15.0
Castle.Core|3.3.0
Castle.Windsor.Lifestyles|0.3.0
Castle.Windsor|3.3.0
FluentAssertions|5.10.3
而不是
AutoFixture|4.15.0
Castle.Core|3.3.0
Castle.Windsor|3.3.0
Castle.Windsor.Lifestyles|0.3.0
FluentAssertions|5.10.3
如图所示,我希望“Castle.Windsor”出现在“Castle.Windsor.Lifestyles”之前。 我很确定我必须使用 IComparer,但我找不到先获取较短名称的方法。
到目前为止,我创建了一个像这样的自定义排序,但它不起作用..
public class PackageComparer : IComparer<string>
{
// Assume that each line has the format: name|number
private readonly Regex packageRegEx = new Regex(@"[\w.]+\|[\d.]+", RegexOptions.Compiled);
public int Compare(string x, string y)
{
var firstPackage = this.packageRegEx.Match(x);
var firstLeft = firstPackage.Groups[1].Value;
var firstRight = firstPackage.Groups[2].Value;
var secondPackage = this.packageRegEx.Match(y);
var secondLeft = secondPackage.Groups[1].Value;
var secondRight = secondPackage.Groups[2].Value;
if (firstLeft < secondLeft)
{
return -1;
}
if (firstRight > secondLeft)
{
return 1;
}
return string.CompareOrdinal(firstSceneAlpha, secondSceneAlpha);
}
}
好吧,您可以使用 Linq,按管道拆分并按包名称排序,然后按版本控制:
var input = @"AutoFixture|4.15.0
Castle.Core|3.3.0
Castle.Windsor.Lifestyles|0.3.0
Castle.Windsor|3.3.0
FluentAssertions|5.10.3
Castle.Core|3.1.0";
var list = input.Split(new string[]{"\r\n","\n"},StringSplitOptions.None).ToList();
list = list
.OrderBy(x => x.Split('|')[0])
.ThenBy(x => new Version(x.Split('|')[1]))
.ToList();
输出:
AutoFixture|4.15.0
Castle.Core|3.1.0
Castle.Core|3.3.0
Castle.Windsor|3.3.0
Castle.Windsor.Lifestyles|0.3.0
FluentAssertions|5.10.3
你可以这样做:
public class YourClassName
{
public string PackageName { get; set; }
public string Pipe { get; set; }
public string Version { get; set; }
}
将您的数据加载到列表中进行排序
List<YourClassName> list = souce of data;
list = SortList<YourClassName>(list, "PackageName");
排序列表方法:
public List<YourClassName> SortList<TKey>(List<YourClassName> list, string sortBy)
{
PropertyInfo property = list.GetType().GetGenericArguments()[0].GetProperty(sortBy);
return list.OrderBy(e => property.GetValue(e, null)).ToList<YourClassName>();
}