Shaun Luttin
Shaun Luttin

Reputation: 141552

Create a list of sequential numbers excluding one number

Requirements:

  1. Create a list of n sequential numbers starting at a.
  2. Exclude number x.

This is the best I have right now, the problem being that it creates n + 1 numbers if x is not within the range.

var numbers = Enumerable
    .Range(a, numberOfDataRowsToAdd + 1)
    .Where(i => i != TechnicalHeaderRowIndex);

Example 1 should produce 0,1,2,3,4,5,6,7,8,9.

var a = 0;
var n = 10; 
var x = 11;

Example 2 should produce 0,1,2,3,4,5,7,8,9,10.

var a = 0;
var n = 10; 
var x = 6;

Here is a Fiddle that demonstrates Mark's answer.

Upvotes: 1

Views: 3796

Answers (6)

Mark Sowul
Mark Sowul

Reputation: 10600

How about

Enumerable.Range(a, n + 1)
          .Where(i => i != x)
          .Take(n);

Upvotes: 5

Ivan Stoev
Ivan Stoev

Reputation: 205629

I don't see what really is the challenge - Linq shortest or fastest or just working. How about the natural (which should also be the fastest Linq based)

var numbers = a <= x && x < a + n ?
    Enumerable.Range(a, x - a).Concat(Enumerable.Range(x + 1, a - x + n)) :
    Enumarble.Range(a, n);

Upvotes: 0

ivamax9
ivamax9

Reputation: 2629

My example, how it can be done without LINQ and extra loop iterations:

 public static IEnumerable<int> GenerateNumbers(int a, int n, int x)
 {
    for (var i = 0; i < n; i++)
    {
        if (a == x)
        {
           i--;
           a++;
           continue;
        }
        yield return a++;
    }
 }

But if you don't want create new method for this purpose, Mark Sowul or Jakub Lortz answers are better.

Upvotes: 2

Renan Ara&#250;jo
Renan Ara&#250;jo

Reputation: 3631

You can drop the last if your enumerable count is bigger than numberOfDataRowsToAdd

Extension method:

public static IEnumerable<T> DropLast<T>(this IEnumerable<T> enumerable)
{
  return enumerable.Take(enumerable.Count()-1);
}

Usage:

var numbers = Enumerable
    .Range(a, numberOfDataRowsToAdd + 1)
    .Where(i => i != TechnicalHeaderRowIndex);

if(numbers.Count() > numberOfDataRowsToAdd)
    numbers = numbers.DropLast();

Upvotes: 0

Dmitry
Dmitry

Reputation: 14059

It makes sense to generate only necessary values instead of generating n + 1 values and then remove x:

Enumerable.Range(a, n).Select(i => i < x ? i : i + 1);

Example 1: 0,1,2,3,4,5,6,7,8,9.
Example 2: 0,1,2,3,4,5,7,8,9,10.

Upvotes: 0

Jakub Lortz
Jakub Lortz

Reputation: 14894

The problem can be described as

  1. Get n + 1 sequential numbers starting from a
  2. If x is in the range, remove x, otherwise remove the maximum number from the list

Translated to C#

int numberToExclude = Math.Min(n + a, x);
var numbers = Enumerable.Range(a, n + 1).Where(i => i != numberToExclude);

Upvotes: 1

Related Questions