首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >如果缺少数,则Linq分裂群

如果缺少数,则Linq分裂群
EN

Stack Overflow用户
提问于 2019-08-31 16:35:05
回答 7查看 299关注 0票数 3

这件事完全把我搞糊涂了。

假设我们有一个整数列表

代码语言:javascript
复制
var list = new List {
   1,
   2,
   3,
   5,
   6,
   7,
   9,
   10    
};

我怎么能把这个分组,这里是1,3,5,7,9-10,这个组被除以,下一个整数丢失了?

EN

回答 7

Stack Overflow用户

回答已采纳

发布于 2019-08-31 17:07:11

看看这个有用不管用。没有循环,只有linq

代码语言:javascript
复制
            List<int> list = new List<int> { 1, 2, 3, 5, 6, 7, 9, 10};
            List<int> splitIndex = list.Skip(1).Select((x,i) => new { x = x, i = i}).Where(x => list[x.i] + 1 != x.x).Select(x => x.i).ToList();
            //add last index
            splitIndex.Add(list.Count - 1);
            var results = splitIndex.Select((x,i) => (i == 0) ? list.Take(x + 1).ToList() : list.Skip(splitIndex[i - 1] + 1).Take(splitIndex[i] - splitIndex[i - 1]).ToList()).ToList();  
票数 7
EN

Stack Overflow用户

发布于 2019-08-31 16:46:44

您不会用简单的LINQ实现它,但是您可以编写自己的扩展方法来处理这种分组。

您必须将其放置在静态类中,并将其称为普通LINQ。

代码语言:javascript
复制
public static class LinqExtensions
{
    public static IEnumerable<IEnumerable<int>> GroupSequential (
        this IEnumerable<int> source)
    {
        var previous = source.First();
        var list = new List<int>() { previous };
        foreach (var item in source.Skip(1))
        {
            if (item - previous != 1)
            {
                yield return list;
                list = new List<int>();
            }
            list.Add(item);
            previous = item;
        }
        yield return list;
    }
}

list.GroupSequential()一样叫它

我觉得这个应该能满足你的需要。

票数 2
EN

Stack Overflow用户

发布于 2019-08-31 17:21:29

我同意@Arion的观点,用一个可读的LINQ方法链可能是不可能的。@jdweng证明我错了:-)

我想提供我的替代解决方案。它是一种扩展方法,它使用自定义的间隔类型。

范围:

代码语言:javascript
复制
public struct Interval
{
    public Interval(int from, int to)
    {
        From = from;
        To = to;
    }

    public int From { get; }
    public int To { get; }

    public IEnumerable<int> Members() => Enumerable.Range(From, To - From + 1);
}

要获取Range中的数字,可以使用Numbers()函数。数字是懒洋洋地生成的,因此,除非您需要它们,否则可以节省空间。

分机:

代码语言:javascript
复制
public static class EnumerableExtensions
{
    public static IEnumerable<Interval> GetIntervals(this IEnumerable<int> numbers)
    {
        var array = numbers.OrderBy(x => x).ToArray();
        var fromIndex = 0;
        var toIndex = fromIndex;
        for (var i = 1; i < array.Length; i++)
        {
            var current = array[i];
            if (current == array[toIndex] + 1)
            {
                toIndex++;
            }
            else if (fromIndex != toIndex)
            {
                yield return new Interval(array[fromIndex], array[toIndex]);
                fromIndex = i;
                toIndex = fromIndex;
            }
        }

        if (toIndex != fromIndex)
        {
            yield return new Interval(array[fromIndex], array[toIndex]);
        }
    }
}

用法:

代码语言:javascript
复制
public void Demo()
{
    var list = new List<int> {1, 2, 3, 5, 6, 7, 9, 10};

    // 1-3, 5-7, 9-10, lazily generated
    var intervals = list.GetIntervals();
    foreach (var interval in intervals) 
    {
        // [1, 2, 3], then [5, 6, 7], then [9, 10], lazily generated
        var members = interval.Members(); 
        foreach (var numberInRange in members)
        {
            // do something with numberInRange
        }
    }
}
票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/57739843

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档