C# 如何获得按标题编号排序的对象列表?
我的C代码中有一个标题对象字典:dictionary daltitles 标题类定义如下:C# 如何获得按标题编号排序的对象列表?,c#,dictionary,C#,Dictionary,我的C代码中有一个标题对象字典:dictionary daltitles 标题类定义如下: class Title { public long TitleID { get; set;} public string TitleText { get; set;} public string TitleNumber { get; set;} } 标题编号可以有以下值,例如:1、1.1、2.10、4.6.5.2.5等。。。未来可能
class Title
{
public long TitleID { get; set;}
public string TitleText { get; set;}
public string TitleNumber { get; set;}
}
标题编号可以有以下值,例如:1、1.1、2.10、4.6.5.2.5等。。。未来可能会有更多的数字
如何从dictionary daltitles中获取按TitleNumber属性排序的词典或标题列表?我想不出一个简单的解决办法
提前谢谢 我不确定我是否理解您希望应用于排序逻辑的规则,但对我来说,LINQ可以做您想做的事情
dico.OrderBy(kvp => kvp.Value.TitleNumber).ToDictionary(kvp => kvp.Key);
这将以某种方式订购您的词典,我相信您可以根据需要调整它。您可以使用cheapo helper功能:
string padded(string s)
{
var p = s.Split('.');
var pp = string.Join("." , p.Select(x => Convert.ToInt16(x).ToString("00000")));
return pp;
}
然后使用linq进行排序:
List<Title> sorted = DAllTitles.OrderBy(x => padded(x.TitleNumber)).ToList();
您可以实现一个类来更正确地控制版本控制
public class TitleNumber : IComparable
{
private int[] Version;
public TitleNumber(string titlenumber)
{
Version = titlenumber.Split('.').Select(x => int.Parse(x)).ToArray();
}
public int CompareTo(object obj)
{
if (obj is TitleNumber other)
{
return CompareTo(other);
}
else
{
throw new ArgumentException($"Object must be of type {nameof(TitleNumber)}");
}
}
public int CompareTo(TitleNumber other)
{
var depth = 0;
var depthThis = Version.Length - 1;
var depthOther = other.Version.Length - 1;
while (true)
{
if (depthThis == depth && depthOther == depth) return 0;
if (depthOther < depth || (depthThis >= depth && Version[depth] > other.Version[depth])) return 1;
if (depthThis < depth || Version[depth] < other.Version[depth]) return -1;
depth++;
}
}
public override bool Equals(object obj) => obj is TitleNumber other && CompareTo(other) == 0;
public override string ToString() => string.Join(".", Version);
}
以如何使用它为例:
var t1 = new TitleNumber("5.34.20");
var t2 = new TitleNumber("4");
var t3 = new TitleNumber("5.34");
var t4 = new TitleNumber("5.34.20.1");
var t5 = new TitleNumber("5.35");
var l = new List<TitleNumber>() { t1, t2, t3, t4, t5 };
var r = l.OrderBy(x => x).ToList();
怎么点的?这两个应该如何排序:2.10 vs 2.9?顺便说一下,字典没有顺序,您需要将它们放入任何顺序或有序集合中。您必须编写一个比较器。一点也不难。然后,您将需要一个自然排序实现。不确定是否有一个内置到.NET中,但首先让我们看看这里是否已经回答了这个问题。您将TitleNumber定义为长类型,但提到了一个可能的值:4.6.5.2.5。这肯定不是很长时间。它是字符串还是长字符串?这在3.1、3.10、3.1中不起作用。1@NicolasDaumalle关于3.1,3.1.1,3.11,3.10的顺序是什么?我用下面的字典var dico=newdictionary{{1,newtitle{TitleID=10,TitleText=text10,TitleNumber=1.1},{2,newtitle{TitleID=20,TitleText=text20,TitleNumber=1.2},{3,新标题{TitleID=30,TitleText=text30,TitleNumber=2.1}},{4,新标题{TitleID=40,TitleText=text40,TitleNumber=1.3}},{5,新标题{TitleID=50,TitleText=text50,TitleNumber=0.5};它按以下顺序输出对象:5,1,2,4,3,这看起来对我来说是正确的。它也可以使用1.2.1这样的值。这就像一个符咒,但我使用linq那样来避免错误:List lalltitlesorted=daltitles.OrderByx=>paddedx.Value.TitleNumber.Selecto=>o.Value.ToList;非常感谢您的帮助!谢谢,我将测试它!
public class TitleNumber : IComparable
{
private int[] Version;
public TitleNumber(string titlenumber)
{
Version = titlenumber.Split('.').Select(x => int.Parse(x)).ToArray();
}
public int CompareTo(object obj)
{
if (obj is TitleNumber other)
{
return CompareTo(other);
}
else
{
throw new ArgumentException($"Object must be of type {nameof(TitleNumber)}");
}
}
public int CompareTo(TitleNumber other)
{
var depth = 0;
var depthThis = Version.Length - 1;
var depthOther = other.Version.Length - 1;
while (true)
{
if (depthThis == depth && depthOther == depth) return 0;
if (depthOther < depth || (depthThis >= depth && Version[depth] > other.Version[depth])) return 1;
if (depthThis < depth || Version[depth] < other.Version[depth]) return -1;
depth++;
}
}
public override bool Equals(object obj) => obj is TitleNumber other && CompareTo(other) == 0;
public override string ToString() => string.Join(".", Version);
}
var t1 = new TitleNumber("5.34.20");
var t2 = new TitleNumber("4");
var t3 = new TitleNumber("5.34");
var t4 = new TitleNumber("5.34.20.1");
var t5 = new TitleNumber("5.35");
var l = new List<TitleNumber>() { t1, t2, t3, t4, t5 };
var r = l.OrderBy(x => x).ToList();