C# 分类章节内容,如14.1.2.3和14.10.1.2.3.4
我有不同深度的章节 所以有14.1和14.4.2以及14.7.8.8.2等等 字母数字排序14.10将出现在14.2之前。那太糟糕了。应该在14.9之后C# 分类章节内容,如14.1.2.3和14.10.1.2.3.4,c#,linq,sorting,C#,Linq,Sorting,我有不同深度的章节 所以有14.1和14.4.2以及14.7.8.8.2等等 字母数字排序14.10将出现在14.2之前。那太糟糕了。应该在14.9之后 有没有一种简单的方法来排序这些,而不添加前导零?f、 e.使用linq?我现在就这么做了,需要一些测试: using System; using System.Collections.Generic; using System.Linq; namespace TestesConsole { class Program {
有没有一种简单的方法来排序这些,而不添加前导零?f、 e.使用linq?我现在就这么做了,需要一些测试:
using System;
using System.Collections.Generic;
using System.Linq;
namespace TestesConsole
{
class Program
{
static void Main(string[] args)
{
string[] vers = new[]
{
"14.10",
"14.9",
"14.10.1",
};
var ordered = vers.OrderBy(x => x, new VersionComparer()).ToList();
}
}
public class VersionComparer : IComparer<string>
{
public int Compare(string x, string y)
{
string[] xs = x.Split('.');
string[] ys = y.Split('.');
int maxLoop = Math.Min(xs.Length, ys.Length);
for (int i = 0; i < maxLoop; i++)
{
if(int.Parse(xs[i]) > int.Parse(ys[i]))
{
return 1;
}
else if(int.Parse(xs[i]) < int.Parse(ys[i]))
{
return -1;
}
}
if(xs.Length > ys.Length)
{
return 1;
}
else if(xs.Length < ys.Length)
{
return -1;
}
return 0;
}
}
}
使用系统;
使用System.Collections.Generic;
使用System.Linq;
命名空间测试解决方案
{
班级计划
{
静态void Main(字符串[]参数)
{
字符串[]vers=new[]
{
"14.10",
"14.9",
"14.10.1",
};
var ordered=vers.OrderBy(x=>x,新版本比较程序()).ToList();
}
}
公共类版本比较程序:IComparer
{
公共整数比较(字符串x、字符串y)
{
字符串[]xs=x.Split('.');
字符串[]ys=y.Split('.');
int maxLoop=Math.Min(xs.Length,ys.Length);
对于(int i=0;iint.Parse(ys[i]))
{
返回1;
}
else if(int.Parse(xs[i])ys.Length)
{
返回1;
}
否则如果(xs.Length
公共类NumberedSectionComparer:IComparer
{
私有整数比较(字符串[]x,字符串[]y)
{
如果(x.长度>y.长度)
return-Compare(y,x);//保存需要单独逻辑的数据。
对于(int i=0;i!=x.长度;++i)
{
int-cmp=int.Parse(x[i])。比较(int.Parse(y[i]);
如果(cmp!=0)
返回cmp;
}
返回x.Length==y.Length?0:-1;
}
公共整数比较(字符串x、字符串y)
{
if(ReferenceEquals(x,y))//捷径
返回0;
如果(x==null)
返回-1;
如果(y==null)
返回1;
尝试
{
返回比较(x.Split('.')、y.Split('.');
}
捕获(格式化异常)
{
抛出新ArgumentException();
}
}
}
var headers=新列表{“14.1.2.3”、“14.1”、“14.9”、“14.2.1”、“14.4.2”、“14.10.1.2.3.4”、“14.7.8.8.2”};
headers.Sort(新的MySorter());
类MySorter:IComparer
{
公共整数比较(字符串x、字符串y)
{
IList a=x.Split('.');
IList b=y.Split('.');
int numToCompare=(a.计数
使用IComparer有一个很大的缺点,就是经常重复相当昂贵的计算,因此我认为预先计算订单标准是一个好主意:
using System;
using System.Collections.Generic;
using System.Linq;
namespace ChapterSort
{
class Program
{
static void Main(string[] args)
{
String[] chapters=new String[] {"14.1","14.4.2","14.7.8.8.2","14.10","14.2","14.9","14.10.1.2.3.4","14.1.2.3" };
IEnumerable<String> newchapters=chapters.OrderBy(x => new ChapterNumerizer(x,256,8).NumericValue);
foreach (String s in newchapters) Console.WriteLine(s);
}
}
public class ChapterNumerizer
{
private long numval;
public long NumericValue {get{return numval;}}
public ChapterNumerizer (string chapter,int n, int m)
{
string[] c = chapter.Split('.');
numval=0;
int j=0;
foreach (String cc in c)
{
numval=n*numval+int.Parse(cc);
j++;
}
while (j<m)
{
numval*=n;
j++;
}
}
}
}
使用系统;
使用System.Collections.Generic;
使用System.Linq;
名称空间章节排序
{
班级计划
{
静态void Main(字符串[]参数)
{
字符串[]章=新字符串[]{“14.1”、“14.4.2”、“14.7.8.8.2”、“14.10”、“14.2”、“14.9”、“14.10.1.2.3.4”、“14.1.2.3”};
IEnumerable newchapters=chapters.OrderBy(x=>newchapternumerizer(x,256,8).NumericValue);
foreach(新章节中的字符串s)Console.WriteLine(s);
}
}
公共类ChapterNumerizer
{
私人长纽瓦尔;
公共长数值值{get{return numval;}}
公共章记数器(字符串章,int n,int m)
{
字符串[]c=章.拆分('.');
numval=0;
int j=0;
foreach(c中的字符串cc)
{
numval=n*numval+int.Parse(cc);
j++;
}
而(j此解更一般
public class SequenceComparer<T> : IComparer<IEnumerable<T>> where T : IComparable<T>
{
public int Compare(IEnumerable<T> x, IEnumerable<T> y)
{
IEnumerator<T> enx = x.GetEnumerator();
IEnumerator<T> eny = y.GetEnumerator();
do
{
bool endx = enx.MoveNext();
bool endy = eny.MoveNext();
if (!endx && !endy)
return 0;
if (!endx)
return -1;
if (!endy)
return 1;
var comp = enx.Current.CompareTo(eny.Current);
if(comp != 0)
return comp;
} while (true);
}
}
公共类SequenceComparer:IComparer其中T:IComparable
{
公共整数比较(IEnumerable x,IEnumerable y)
{
IEnumerator enx=x.GetEnumerator();
IEnumerator eny=y.GetEnumerator();
做
{
bool endx=enx.MoveNext();
bool endy=eny.MoveNext();
如果(!endx&&!endy)
返回0;
如果(!endx)
返回-1;
如果(!endy)
返回1;
var comp=enx.电流比较器(eny.电流);
如果(组件!=0)
返回补偿;
}虽然(正确);
}
}
然后使用:
var sv = vers.Select(v => new { Key = v, Split = v.Split('.').Select(Int32.Parse) });
var ordered = sv.OrderBy(x => x.Split, new SequenceComparer<int>()).Select(x => x.Key);
var sv=vers.Select(v=>new{Key=v,Split=v.Split('.').Select(Int32.Parse)});
var ordered=sv.OrderBy(x=>x.Split,new SequenceComparer()).Select(x=>x.Key);
作为小型LINQ单衬板:
List<string> chapters= new List<string>()
{
"14.1",
"14.4.2",
"14.7.8.8.2",
"14.10",
"14.2"
};
chapters.OrderBy(c => Regex.Replace(c, "[0-9]+", match => match.Value.PadLeft(10, '0')));
List chapters=新列表()
{
"14.1",
"14.4.2",
"14.7.8.8.2",
"14.10",
"14.2"
};
chapters.OrderBy(c=>Regex.Replace(c,“[0-9]+”,match=>match.Value.PadLeft(10,'0'));
独立于级别,但肯定不是最佳性能
学分将我认为公认的答案也适用于您的情况。尽管您将被限制为四个“级别”。看起来很不错,四个级别-好。更多想法也不错:)我首先测试了这个解决方案,出于某种原因,它在大规模处理中运行,以最大执行时间结束…非常感谢您的时间,但对我来说,由于某种神秘的原因,它工作得不太好。|我没有加载测试,只是出于好奇,您的收藏中有多少ITEN?大约有1500个不同的项目,170个总共0个或更多:)@fujiy
var sv = vers.Select(v => new { Key = v, Split = v.Split('.').Select(Int32.Parse) });
var ordered = sv.OrderBy(x => x.Split, new SequenceComparer<int>()).Select(x => x.Key);
List<string> chapters= new List<string>()
{
"14.1",
"14.4.2",
"14.7.8.8.2",
"14.10",
"14.2"
};
chapters.OrderBy(c => Regex.Replace(c, "[0-9]+", match => match.Value.PadLeft(10, '0')));