【问题标题】:Split list into two lists with single LINQ statement [duplicate]使用单个 LINQ 语句将列表拆分为两个列表 [重复]
【发布时间】:2014-03-08 12:33:02
【问题描述】:

我想用一个 LINQ 语句将一个列表分成两个列表。我目前正在这样做:

var listA = allItems.Where(item => item.IsUseful);
var listB = allItems.Except(listA);

但是我想要一个查询语法中的单个 LINQ 语句,它只遍历原始列表一次,并返回一个匿名类型,其中两个列表作为属性(例如 results.ListA;results.ListB)。

【问题讨论】:

  • 请提供样本数据。

标签: c# linq


【解决方案1】:

这将为您提供一个带有两个列表的Dictionary<bool, List<T>>,您可以使用result[true]result[false] 轻松获取您的列表:

var result = allItems.GroupBy(item => item.IsUseful)
                     .ToDictionary(x => x.Key,x => x.ToList());

【讨论】:

  • 绝对是更具可读性的解决方案。
  • 如果所有值都相同(全为真或全为假)则中断。使用 ToLookup。
【解决方案2】:

我不知道有一种方法可以通过像“Results.ListA”和“Result.ListB”这样的命名属性来访问它,而无需使用反射,这会更昂贵,但这会让你非常接近通过访问职位:

var results = allItems.GroupBy(item => item.IsUseful).ToList();
results.First();  // this will access listA
results.Last();   // this will access listB

或者在 query 语法中,就像你在问题中所说的那样:

var results = (from x in allItems
               group x by x.IsUseful
               into groupings
               select groupings).ToList(); 

results.First();  // this will access listA
results.Last();   // this will access listB

【讨论】:

  • 组有一些保证的固有顺序吗? (即results = {GroupTrue, GroupFalse},其中GroupTrue 是包含满足条件.IsUseful 的元素的组。