首页
学习
活动
专区
工具
TVP
发布
社区首页 >问答首页 >我可以在没有两个查询的情况下通过布尔条件将IEnumerable一分为二吗?

我可以在没有两个查询的情况下通过布尔条件将IEnumerable一分为二吗?
EN

Stack Overflow用户
提问于 2010-12-29 04:39:48
回答 3查看 11.7K关注 0票数 76

我可以使用LINQ和只有一条IEnumerable<T> /LINQ语句将一个查询拆分为两个查询吗?

我希望避免对IEnumerable<T>进行两次迭代。例如,是否可以将下面最后两个语句组合在一起,这样allValues就只被遍历一次?

代码语言:javascript
复制
IEnumerable<MyObj> allValues = ...
List<MyObj> trues = allValues.Where( val => val.SomeProp ).ToList();
List<MyObj> falses = allValues.Where( val => !val.SomeProp ).ToList();
EN

回答 3

Stack Overflow用户

回答已采纳

发布于 2010-12-29 04:41:46

您可以使用以下命令:

代码语言:javascript
复制
var groups = allValues.GroupBy(val => val.SomeProp);

强制立即求值,如您的示例所示:

代码语言:javascript
复制
var groups = allValues.GroupBy(val => val.SomeProp)
                      .ToDictionary(g => g.Key, g => g.ToList());
List<MyObj> trues = groups[true];
List<MyObj> falses = groups[false];
票数 74
EN

Stack Overflow用户

发布于 2010-12-29 09:41:50

有些人喜欢字典,但我更喜欢查找,因为键丢失时的行为。

代码语言:javascript
复制
IEnumerable<MyObj> allValues = ...
ILookup<bool, MyObj> theLookup = allValues.ToLookup(val => val.SomeProp);

// does not throw when there are not any true elements.
List<MyObj> trues = theLookup[true].ToList();
// does not throw when there are not any false elements.
List<MyObj> falses = theLookup[false].ToList();

不幸的是,这种方法枚举了两次-一次是创建查找,另一次是创建列表。

如果你真的不需要列表,你可以将其简化为一次迭代:

代码语言:javascript
复制
IEnumerable<MyObj> trues = theLookup[true];
IEnumerable<MyObj> falses = theLookup[false];
票数 72
EN

Stack Overflow用户

发布于 2017-05-04 04:15:27

为方便起见,请复制意大利面扩展方法。

代码语言:javascript
复制
public static void Fork<T>(
    this IEnumerable<T> source,
    Func<T, bool> pred,
    out IEnumerable<T> matches,
    out IEnumerable<T> nonMatches)
{
    var groupedByMatching = source.ToLookup(pred);
    matches = groupedByMatching[true];
    nonMatches = groupedByMatching[false];
}

或者在C# 7.0中使用元组

代码语言:javascript
复制
public static (IEnumerable<T> matches, IEnumerable<T> nonMatches) Fork<T>(
    this IEnumerable<T> source,
    Func<T, bool> pred)
{
    var groupedByMatching = source.ToLookup(pred);
    return (groupedByMatching[true], groupedByMatching[false]);
}

// Ex.
var numbers = new [] { 1, 2, 3, 4, 5, 6, 7, 8 };
var (numbersLessThanEqualFour, numbersMoreThanFour) = numbers.Fork(x => x <= 4);
票数 14
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/4549339

复制
相关文章

相似问题

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