Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/linq/3.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 分类章节内容,如14.1.2.3和14.10.1.2.3.4_C#_Linq_Sorting - Fatal编程技术网

C# 分类章节内容,如14.1.2.3和14.10.1.2.3.4

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 {

我有不同深度的章节

所以有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
    {
        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')));