【问题标题】:LINQ selecting distinct from 4 IEnumerable listsLINQ 从 4 个 IEnumerable 列表中选择不同
【发布时间】:2010-11-01 09:10:41
【问题描述】:

想象四个列表,都至少有这个Id字符串属性,但可能还有其他属性:

public class A //or B, C, D
{
    public string Id { get; set; }
    //..other properties
}

//so:  
List<A> a1 = new List<A>();
List<B> a2 = new List<B>();
List<C> a3 = new List<C>();
List<D> a4 = new List<D>();

我想在以下位置选择所有 DISTINCT id: a1,结合a2、a3和a4

我认为 LINQ 语法会是理想的,但是如何将它们组合成具有单个字符串属性的 IEnumerable 结果,例如具有 A 类定义的东西。

【问题讨论】:

    标签: c# linq ienumerable distinct


    【解决方案1】:

    你可以连接相同类型的IEnumerables,然后选择你需要的项目。

    var query = a1
        .Concat(a2)
        .Concat(a3)
        .Concat(a4)
        .Select(a => a.ID)
        .Distinct();
    

    编辑:基于新问题...在单个查询中无法从不同的列表类型中进行选择。最好的方法是使用一个包含您选择的属性的通用类型,然后使用基本类型运行上述查询。

    【讨论】:

      【解决方案2】:

      它们真的都是同一类型的列表吗?或者你有没有

      List<A> a1 = new List<A>();
      List<B> a2 = new List<B>();
      List<C> a3 = new List<C>();
      List<D> a4 = new List<D>();
      

      并且您想将它们结合起来,因为所有 4 种类型都有一个共同的字符串 Id 属性?

      好的,您的编辑表明我在正确的轨道上。您需要一个定义字符串 Id 属性的接口,并且每个类型 A、B、C 和 D 都需要实现该接口。

      然后每个列表都将是接口类型,并且连接答案将起作用。

      如果您无法定义接口,那么您可以使用 LINQ 查询每个列表中的 Id 字段(您应该得到 IQueryable&lt;String&gt; 结果),然后连接这些结果。

      编辑:这是一个 LINQ 查询,应该可以为您提供所需的内容:

      var uniqueIds = (from a in a1
                       select a.Id).Concat(
                       from b in a2
                       select b.Id).Concat(
                       from c in a3
                       select c.Id).Concat(
                       from d in a4
                       select d.Id).Distinct();
      

      【讨论】:

        【解决方案3】:

        这也有效:

        new[] {a1, a2, a3, a4}.SelectMany(x => x.Select(y => y.Id)).Distinct();
        

        【讨论】:

        • 由于 a1、a2、a3 和 a4 是不同的类型,因此对于隐式类型化数组,将没有“最佳类型”匹配...编译器错误 CS0826 (is.gd/Udlw)
        • 经过我的回答澄清,a1、a2、a3和a4可能有不同的类型。
        【解决方案4】:

        由于它们是不同的类型,我会先选择 Id 属性 以获取 IEnumerable,然后将结果连接起来:

        var query = a1.Select(a=> a.Id)
                      .Concat(a2.Select(b=> b.Id))
                      .Concat(a3.Select(c=> c.Id))
                      .Concat(a4.Select(d=> d.Id))
                      .Distinct();
        

        【讨论】:

        • 与我最终得出的结果完全相同。问题的第一个版本并没有完全清楚地表明它们是不同的类型。
        【解决方案5】:

        联合

        当然,你可以简化:

        var uniqueIds = (from a in a1
                         select a.Id).Concat(
                         from b in a2
                         select b.Id).Concat(
                         from c in a3
                         select c.Id).Concat(
                         from d in a4
                         select d.Id).Distinct();
        

        通过使用 Union(它执行一个隐含的 'Distinct'),变成:

        var uniqueIds =  (from a in a1
                         select a.Id).Union(
                         from b in a2
                         select b.Id).Union(
                         from c in a3
                         select c.Id).Union(
                         from d in a4
                         select d.Id);
        

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2010-10-03
          • 1970-01-01
          • 2017-11-27
          • 2012-03-12
          • 1970-01-01
          相关资源
          最近更新 更多