Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/278.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

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# 获取int集合的可能范围_C#_Linq_Int_Range - Fatal编程技术网

C# 获取int集合的可能范围

C# 获取int集合的可能范围,c#,linq,int,range,C#,Linq,Int,Range,我有一个id列表(int)如下 是否有一种快速/智能的方式(linq?)获取所有id或范围(如果可能)? 结果应该类似于[1-3,5,7-8,11,13-14] 当然,循环和计算int值以获得结果很容易,但我确信一定有一种更简单的方法可以做到这一点。老式的方法,使用一个for循环 try { List<int> i = new List<int>() { 1, 2, 3, 5, 7, 8, 11, 13, 14 }; int istart = i[0]

我有一个id列表(
int
)如下

是否有一种快速/智能的方式(linq?)获取所有id或范围(如果可能)? 结果应该类似于
[1-3,5,7-8,11,13-14]


当然,循环和计算int值以获得结果很容易,但我确信一定有一种更简单的方法可以做到这一点。

老式的方法,使用一个for循环

try
{
     List<int> i = new List<int>() { 1, 2, 3, 5, 7, 8, 11, 13, 14 };
     int istart = i[0];
     bool flag = false;
     // Use StringBuilder
     for(int index = 0;index<i.Count-1;index++)
     {
         if ((i[index] + 1) == i[index + 1])
         {
              flag = true;
              continue;
         }
         else
         {
              if (!flag)
                  Console.Write(istart);
              else
                  Console.Write(istart + "-" + i[index]);

              Console.Write(",");

              flag = false;
              istart = i[index + 1];
          }
      }
      if (istart + 1 == i[i.Count - 1])
          Console.Write(istart + "-" + i[i.Count - 1]);
      else
          Console.WriteLine(istart);
}
catch(Exception ex)
{
       Console.WriteLine(ex.Message);
}
Console.WriteLine();
Console.WriteLine("Done");
Console.Read();
试试看
{
列表i=新列表(){1,2,3,5,7,8,11,13,14};
int istart=i[0];
布尔标志=假;
//使用StringBuilder

对于(int index=0;index有一种linq方法可以做到这一点(如果数字不重复),但我不确定这是否更容易:

int last = -1;
int rank = 0;
IEnumerable<string> grouped = arr
    .GroupBy(i =>
    {
        rank += i - last - 1;
        last = i;
        return rank;
    })
    .Select(g => g.Count() == 1 ? g.First().ToString()
                : g.First().ToString() + "-" + g.Last().ToString());
守则:

int size = 10000000;
int[] arr = new int[size];
Random rnd = new Random(1);

arr[0] = 0;
for(int i = 1; i < size; ++i)
{
    if (rnd.Next(100) < 25)
    {
        arr[i] = arr[i - 1] + 2;
    }
    else
    {
        arr[i] = arr[i - 1] + 1;
    }
}         

System.Diagnostics.Stopwatch st = new System.Diagnostics.Stopwatch();
st.Start();
var res = Group(arr).ToList();
st.Stop();

MessageBox.Show(st.ElapsedMilliseconds.ToString());
MessageBox.Show(res.Sum(s => s.Length).ToString());// to be sure the work is done
int size=10000000;
int[]arr=新的int[size];
随机rnd=新随机(1);
arr[0]=0;
对于(int i=1;is.Length.ToString());//确保工作完成

免责声明这在大列表上非常慢,您也应该做一个明确的说明

这应该能奏效

    static void Main(string[] args)
    {
        //a list with a possible of duplicate
        var theList = (new int[] { 1, 2, 3, 5, 7, 8, 11, 13, 14, 13 }).OrderBy(x => x).ToList();

        var step1 = theList.Select((a, b) =>  theList.Skip(b).TakeWhile((x, y) => a == x || theList[b + y] - 1 == theList[b + y - 1]));

        var step2 = step1.GroupBy(x => x.Last())
                         .Select(x => x.SelectMany(y => y).Distinct())
                         .Select(x => x.Count() > 1 ? string.Format("{0}-{1}", x.First(), x.Last()) : x.First().ToString());


        var result = string.Format("[{0}]", string.Join(", ", step2));

    }

考虑到有序列表和唯一ID,我认为最简单的方法是使用classic for和while

List id=newlist(){1,2,3,5,7,8,11,13,14};
int i=0;
布尔伊斯兰格;

对于(i=0;i生成范围的逻辑是什么?为什么不是1-5、3-8等?是否有一种快速/智能的方法(linq?)-如果“快速”是指执行速度,那么“foreach”总是比linq快,你也应该在答案中加入实际的基准代码;-)@Fredou ok,adddi在我的答案中添加了一点免责声明;-)@弗雷多我同意前半部分的免责声明,但不理解“你也应该做一个与众不同的”。
  simple loop:  328MB, 1.2sec
      my linq:  790MB, 2.7sec 
 Fredous linq:  1100MB, 7days (estimated)
int size = 10000000;
int[] arr = new int[size];
Random rnd = new Random(1);

arr[0] = 0;
for(int i = 1; i < size; ++i)
{
    if (rnd.Next(100) < 25)
    {
        arr[i] = arr[i - 1] + 2;
    }
    else
    {
        arr[i] = arr[i - 1] + 1;
    }
}         

System.Diagnostics.Stopwatch st = new System.Diagnostics.Stopwatch();
st.Start();
var res = Group(arr).ToList();
st.Stop();

MessageBox.Show(st.ElapsedMilliseconds.ToString());
MessageBox.Show(res.Sum(s => s.Length).ToString());// to be sure the work is done
    static void Main(string[] args)
    {
        //a list with a possible of duplicate
        var theList = (new int[] { 1, 2, 3, 5, 7, 8, 11, 13, 14, 13 }).OrderBy(x => x).ToList();

        var step1 = theList.Select((a, b) =>  theList.Skip(b).TakeWhile((x, y) => a == x || theList[b + y] - 1 == theList[b + y - 1]));

        var step2 = step1.GroupBy(x => x.Last())
                         .Select(x => x.SelectMany(y => y).Distinct())
                         .Select(x => x.Count() > 1 ? string.Format("{0}-{1}", x.First(), x.Last()) : x.First().ToString());


        var result = string.Format("[{0}]", string.Join(", ", step2));

    }
List<int> ids = new List<int>() { 1, 2, 3, 5, 7, 8, 11, 13, 14 };
                int i = 0;
                bool isrange;

                for(i=0;i<ids.Count;i++)
                {
                    isrange = false;
                    Console.Write(ids[i]);

                    while (i < ids.Count-1 && ids[i + 1] == ids[i] + 1)
                    {
                        i++;
                        isrange = true;
                    }

                    if (isrange)
                        Console.Write("-" + ids[i]);

                    if (!(i + 1 == ids.Count))
                        Console.Write(",");
                }