加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 百科 > 正文

c# – 使用linq拆分列表

发布时间:2020-12-15 04:26:45 所属栏目:百科 来源:网络整理
导读:我有以下代码: var e = someList.GetEnumerator(); var a = new ListFoo(); var b = new ListFoo(); while(e.MoveNext()) { if(CheckCondition(e.Current)) { b.Add(e.Current); break; } a.Add(e.Current); }while(e.MoveNext()) b.Add(e.Current) 这看起
我有以下代码:
var e = someList.GetEnumerator();
  var a = new List<Foo>();
  var b = new List<Foo>();
  while(e.MoveNext())  {
     if(CheckCondition(e.Current)) {
         b.Add(e.Current);
         break;
     }
     a.Add(e.Current);
 }

while(e.MoveNext())
  b.Add(e.Current)

这看起来很丑陋基本上,遍历列表并将元素添加到一个列表中,直到某些条件启动,并将其余的添加到另一个列表.

有没有更好的方法,例如使用linq? CheckCondition()是昂贵的,列表可能是巨大的,所以我宁愿不做任何迭代列表两次.

解决方法

这是一个解决方案,将枚举列表两次,但它不会第二次检查条件,所以它应该更快:
var a = someList.TakeWhile(x => !CheckCondition(x)).ToList();
var b = someList.Skip(a.Count).ToList();

如果someList实现IList< T>,则每个项目实际上仅被枚举一次,因此不会有任何惩罚.
我认为Skip针对IList< T>的情况进行了优化,但显然不是…但是您可以轻松实现使用此优化的自己的Skip方法(请参阅Jon Skeet’s article关于此)

如果有一个TakeUntil方法,它会更加优雅…我们可以轻松创建它:

public static IEnumerable<TSource> TakeUntil<TSource>(this IEnumerable<TSource> source,Func<TSource,bool> predicate)
{
    foreach(var item in source)
    {
        if (predicate(item))
            break;
        yield return item;
    }
}

使用这种方法,代码变成:

var a = someList.TakeUntil(CheckCondition).ToList();
var b = someList.Skip(a.Count).ToList();

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读