8

有没有办法使用 LINQ 检查整数列表是否是“连续的” - 即 1、2、3、4、5 或 14、15、16、17、18?

4

4 回答 4

25

你可以通过Enumerable.Zip做到这一点:

bool sequential = values.Zip(values.Skip(1), (a,b) => (a+1) == b).All(x => x);

这通过获取每对值,并检查第二个是否比第一个大 1 并返回布尔值来工作。如果所有对都符合标准,则值是连续的。


鉴于这是一个整数列表,您可以使用以下方法更有效地执行此操作:

bool sequential = values.Skip(1).Select((v,i) => v == (values[i]+1)).All(v => v);

这仅适用于可以通过索引访问的序列。请注意,我们使用values[i],而不是values[i-1],因为Skip调用有效地移动了索引。

于 2013-04-10T00:08:22.723 回答
15
bool isSequential = Enumerable.Range(values.Min(), values.Count())
                              .SequenceEqual(values);
于 2013-04-10T00:15:21.520 回答
2

另一种选择是使用Aggregate仅迭代序列一次。

请注意,与AllReed Copsey 建议的不同Aggregate,条件失败时不能在中间停止......

var s = new int[] {3,4,5,6}.ToList();

var isSequential = s.Aggregate
  (
      new {PrevValue = 0, isFirst = true, Success = true} ,
      (acc, current) => 
          new {
                  PrevValue = current,
                  isFirst = false, 
                  Success = acc.Success && (acc.isFirst || (acc.PrevValue == current - 1))
               }
  )
  .Success;

更高级的版本将是具有携带先前值的迭代器或特殊代码,该代码将在“First and the rest”上拆分迭代器,从而允许对任何可枚举的单次迭代实现 Reed 的解决方案。

于 2013-04-10T02:00:28.900 回答
-1

如果您已经知道列表中的数字是唯一的,并且也是排序的,那么最简单的顺序检查就是

lst[lst.Count - 1] - lst[0] == lst.Count - 1

假设列表中至少有 1 个元素。

于 2016-07-01T02:59:46.077 回答