使用linq获取整数范围

Jes*_*sse 7 .net linq

我正在寻找一种计算给定数字范围的方法,例如.

如果我有H555,H567,H589,H590,H591,H592,H593,H594,H595,H596,H597

我想输出H555,H567,H589-H597.

我查看了相关问题,但找不到任何类似我正在寻找的内容.

谢谢

Jon*_*eet 8

好吧,我会做这样的事情:

public sealed class Range
{
    public int Low { get; private set; }
    public int High { get; private set; }

    public Range(int low, int high)
    {
        this.Low = low;
        this.High = high;
    }
}
Run Code Online (Sandbox Code Playgroud)

然后(完全未经测试,甚至可能无法编译,但希望你会得到漂移):

public static IEnumerable<Range> FindRanges(IEnumerable<int> values)
{
    using (IEnumerator<int> iterator = values.GetEnumerator())
    {
        if (!iterator.MoveNext())
        {
            yield break;
        }
        int low = iterator.Current;
        int high = low;
        while (iterator.MoveNext())
        {
            int next = iterator.Current;
            if (next > high + 1)
            {
                // Previous range (or possibly single value) has finished
                yield return new Range(low, high);
                low = next;
            }
            high = next;
        }
        // Yield trailing range
        yield return new Range(low, high);
    }
}
Run Code Online (Sandbox Code Playgroud)

老实说,我认为使用直接LINQ并不是特别容易.

编辑:为了适应这一点,现在一切都以H开头,只需使用:

var numbers = strings.Select(x => int.Parse(x.Substring(1));
var ranges = FindRanges(numbers);

var rangeStrings = ranges.Select(r => r.High == r.Low 
                                   ? "H" + r.Low : "H" + r.Low + "-" + r.High);
var result = string.Join(",", rangeStrings);
Run Code Online (Sandbox Code Playgroud)


And*_*rey 4

我认为 Linq 在这里确实是开销很大,但如果你想要它在这里,你可以:

        int[] arr = { 555, 567, 589, 590, 591, 592, 593, 594, 595, 596, 597 };
        int gr = 0;
        var q = arr
            .Skip(1)
            .Select((x, i) => new { x, group = (x - arr[i]) == 1 ? gr : gr++ })
            .GroupBy( a => a.group)
            .Select(
                a => a.Count() == 1 
                    ? a.First().x.ToString() 
                    : string.Format("{0}-{1}", a.First().x, a.Last().x));
        foreach (var item in q)
        {
            Console.Write(item);
            Console.Write(", ");
        }
Run Code Online (Sandbox Code Playgroud)

  • @Jesse,好吧,我个人更喜欢乔恩的答案。无论是CPU还是内存的性能都更好。我只是想展示如何在 Linq 中执行此操作,这并不意味着您应该在 Linq 中执行此操作。 (2认同)