微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

c# – 使用LINQ拆分数组

假设我有一个清单
var listofInt = new List<int> {1,2,3,4,7,8,12,13,14}

如何使用LINQ获取列表列表,如下所示:

{{1,4},{7,8},{12,14}}

所以,我必须取连续值并将它们分组到列表中.

解决方法

您可以创建扩展方法(我省略了源检查),它将迭代源并创建连续项组.如果source中的下一项不连续,则会产生当前组:
public static IEnumerable<List<int>> ToConsecutiveGroups(
    this IEnumerable<int> source)
{
    using (var iterator = source.GetEnumerator())
    {
        if (!iterator.MoveNext())
        {
            yield break;
        }
        else
        {                    
            int current = iterator.Current;
            List<int> group = new List<int> { current };

            while (iterator.MoveNext())
            {
                int next = iterator.Current;
                if (next < current || current + 1 < next)
                {
                    yield return group;
                    group = new List<int>();                            
                }

                current = next;
                group.Add(current);
            }

            if (group.Any())
                yield return group;
        }                
    }
}

用法很简单:

var listofInt = new List<int> { 1,14 };
var groups = listofInt.ToConsecutiveGroups();

结果:

[
  [ 1,4 ],[ 7,8 ],[ 12,14 ]
]

更新:这是此扩展方法的通用版本,它接受谓词以验证是否应将两个值视为连续的:

public static IEnumerable<List<T>> ToConsecutiveGroups<T>(
    this IEnumerable<T> source,Func<T,T,bool> isConsequtive)
{
    using (var iterator = source.GetEnumerator())
    {
        if (!iterator.MoveNext())
        {
            yield break;
        }
        else
        {                    
            T current = iterator.Current;
            List<T> group = new List<T> { current };

            while (iterator.MoveNext())
            {
                T next = iterator.Current;
                if (!isConsequtive(current,next))
                {
                    yield return group;
                    group = new List<T>();                            
                }

                current = next;
                group.Add(current);
            }

            if (group.Any())
                yield return group;
        }                
    }
}

用法很简单:

var result = listofInt.ToConsecutiveGroups((x,y) => (x == y) || (x == y - 1));

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。

相关推荐