Question: I am looking to extract ranges from an list of integers using linq:

for example I am looking to split the following list: 

```
List<int> numberList = new List<int>() { 30, 60, 90, 120, 150, 180, 270, 300, 330 };  

```

into a list of integer ranges that will look like:

```
{ 30, 180 }
{ 270, 330 }

```

ie: where the next seq is greater than 30

another example : 

```
List<int> numberList = new List<int>() { 30, 60, 120, 150, 270, 300, 330 };  

```

into a list of integer ranges that will look like:

```
{ 30, 60 }
{ 120, 150 }
{ 270, 330 }

```

I have tried with for loops to find the best way possible however I don't
know where to start trying to use a linq query to do this.

Answer: 
You could write a method to handle the split:

```
IEnumerable<IList<int>> SplitValues(IList<int> input, int difference = 30)
{
    List<int> results = new List<int>();
    int last = input.First();
    foreach(var value in input)
    {
        if (value - last > difference)
        {
            yield return new[] {results.First(), results.Last()};
            results = new List<int>();
        }

        results.Add(value);
        last = value;
    }

    yield return new[] {results.First(), results.Last()};
}

```

This matches your specifications as described, returning:

```
{ 30, 60 }
{ 120, 150 }
{ 270, 330 }

```

Note that a single value within the collection without a range will be duplicated. For example, `{ 30, 120, 150 }` will return:

```
{ 30, 30 }
{ 120, 150 }

```
Well. There are many ways to do so and all have their pros and cons.
So here's yet another solution, hope it will be helpful to someone.

```
public static IEnumerable<TSource[]> ToRanges<TSource>(
    this IEnumerable<TSource> source, Func<TSource, TSource, TSource, bool> isNear)
{            
    List<TSource[]> result = source./*OrderBy(value => value).*/Aggregate(
        new List<TSource[]> { new[] { source.First(), source.First() } },
        (ranges, currentValue) => {
            TSource[] currentRange = ranges.Last();
            TSource previousValue = currentRange[1];

            if (isNear(currentRange[0], previousValue, currentValue))
                currentRange[1] = currentValue;
            else
                ranges.Add(new[] { currentValue, currentValue});

            return ranges;
        }
    );

    return result;
}

```

Example usage:

```
List<int> numbers = new List<int>() { 30, 60, 90, 120, 150, 180, 270, 300, 330 };

// split by max difference
numberList.ToRanges(
    (first, previous, current) => current - previous <= 30).ToArray();
// { 30, 180 }
// { 270, 330 }

// split by max range
numberList.ToRanges(
    (first, previous, current) => current - first <= 90).ToArray();
// { 30, 120 }
// { 150, 180 }
// { 270, 330 }

```

In addition, you can split not only integers but also, for example, words by their first letter. Or `DateTime`/`TimeSpan`. Or whatever you want.