Wilson
Wilson

Reputation: 8768

Check if a list of integers increments by one

Is there a way, with LINQ, to check if a list of integers are "sequential" - ie 1,2,3,4,5 or 14,15,16,17,18?

Upvotes: 8

Views: 5570

Answers (4)

Cine
Cine

Reputation: 4402

If you already know that the numbers you have in your list is unique, and also sorted, then the simplest check for sequential is just

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

Assume atleast 1 element in list.

Upvotes: -1

Alexei Levenkov
Alexei Levenkov

Reputation: 100545

One more option is to use Aggregate to iterate sequence only once.

Note that unlike All suggested by Reed Copsey Aggregate can't stop in the middle when condition fails...

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;

Fancier version would be to have iterator that carries previous value along or special code that would split iterator on "First and the rest" allowing to implement Reed's solution with single iteration for any enumerable.

Upvotes: 2

Reed Copsey
Reed Copsey

Reputation: 564641

You could do this via Enumerable.Zip:

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

This works by taking each pair of values, and checking to see if the second is 1 more than the first, and returning booleans. If all pairs fit the criteria, the values are sequential.


Given that this is a list of integers, you can do this slightly more efficiently using:

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

This will only work on sequences which can be accessed by index. Note that we use values[i], not values[i-1], as the Skip call effectively shifts the indices.

Upvotes: 25

Jacob Seleznev
Jacob Seleznev

Reputation: 8141

bool isSequential = Enumerable.Range(values.Min(), values.Count())
                              .SequenceEqual(values);

Upvotes: 16

Related Questions