0

How to get minimum available number in list of integers with LINQ? Number can not be lower than 10.

List<int> numbers = new List<int>() { 10, 11, 12, 22, 23 };

I want to return 13 in this case.

List<int> numbers1 = new List<int>() { 11, 12, 22, 23 };

I want to return 10 in this case

How can I do it with LINQ?

Uwe Keim
  • 39,551
  • 56
  • 175
  • 291

2 Answers2

3

I'd use this:

List<int> numbers = new List<int>() { 11, 12, 22, 23 };

int result = Enumerable.Range(10, numbers.Count + 1).First(x => !numbers.Contains(x));

The use of numbers.Count + 1 handles the case where List<int> numbers = new List<int>() { 10, 11, 12, 13, 14, 15 };

Enigmativity
  • 113,464
  • 11
  • 89
  • 172
  • 1
    Note that this is quadratic. It won't matter if `numbers` is small, but you will notice the slowdown if it's large. – canton7 Feb 10 '19 at 11:43
  • @canton7 - I did consider that, but I felt that it was unlikely that we're dealing with a large enough list to make it an issue. I did initially consider using a `HashSet` but I felt that the time to compute it might have been more significant than a single partial search. Since the OP's list are all increasing then maybe a simple binary search would be best. – Enigmativity Feb 10 '19 at 13:16
  • I completely agree. Just wanted to highlight it in case someone with a similar problem but more numbers came across it. – canton7 Feb 10 '19 at 13:33
0

If the input list is always sorted, you can take advantage of this and do a simple linear search:

List<int> numbers = new List<int>() { 11, 12, 13, 14 };
int result = numbers
    .Zip(
        numbers.Skip(1).Concat(new[] { int.MaxValue }),
        (a, b) => (next: a+1, b))
    .FirstOrDefault(x => x.next != x.b)
    .next;

This is more ugly than @Enigmativity's solution, but it has the advantage of being linear rather than quadratic, which will have an impact if the list of numbers is large.

Personally, I'd just have written this as a cheap linear for loop:

for (int i = 0; i < numbers.Count - 1; i++)
{
    int next = numbers[i] + 1;
    if (next != numbers[i + 1])
    {
        return next;
    }
}
return numbers[numbers.Count - 1] + 1;
canton7
  • 37,633
  • 3
  • 64
  • 77