简体   繁体   English

LINQ选择与4个IEnumerable列表不同

[英]LINQ selecting distinct from 4 IEnumerable lists

Imagine four lists, all at least have this Id string property, but may have other properties: 想象一下四个列表,至少都有这个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>();

I want to select all DISTINCT ids in: a1, combined with a2, a3 and a4 我想选择所有DISTINCT ID:a1,结合a2,a3和a4

I thought LINQ syntax would be ideal but how do you combine these to an IEnumerable result with a single string property, for example something with a definition of class A. 我认为LINQ语法是理想的,但是如何将它们与具有单个字符串属性的IEnumerable结果相结合,例如具有类A定义的东西。

Since they are different types, I would select first the Id property to get an IEnumerable<string>, and then concatenate the results: 由于它们是不同的类型,我首先选择Id属性来获取IEnumerable <string>,然后连接结果:

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();

这也有效:

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

Union 联盟

Of course, you can simplify this: 当然,你可以简化这个:

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();

By using Union (which does an implicit 'Distinct'), to become: 通过使用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);

Are they really all lists of the same type? 它们真的是所有相同类型的列表吗? Or do you have 或者你有

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

and you want to combine those because all 4 types have a common string Id property? 并且你想组合这些,因为所有4种类型都有一个共同的字符串Id属性?

OK, your edit shows I was on the right track. 好的,你的编辑显示我在正确的轨道上。 You need an Interface that defines the string Id property and each type A, B, C and D need to implement that Interface. 您需要一个定义字符串Id属性的接口,并且每个类型A,B,C和D都需要实现该接口。

Then each list will be of the Interface type and the concat answers will work. 然后每个列表将是接口类型,concat答案将起作用。

If you don't have ability to define the interface, then you could use LINQ to query each list for only the Id field (you should get IQueryable<String> results) and then concat those results. 如果您没有能力定义接口,那么您可以使用LINQ仅查询每个列表的Id字段(您应该获得IQueryable<String>结果),然后连接这些结果。

Edit: Here's a LINQ query that should give you what you're looking for: 编辑:这是一个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();

You can concat IEnumerables of the same type, and then select the item you need. 您可以连接相同类型的IEnumerables,然后选择您需要的项目。

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

EDIT: Based on the new question... Selecting from different list types isn't possible in a single query. 编辑:基于新问题...在单个查询中无法从不同的列表类型中进行选择。 The best way to do that would be to have a common type that includes the property you're selecting and then run the above query with the base type. 最好的方法是使用包含您正在选择的属性的公共类型,然后使用基类型运行上述查询。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM