繁体   English   中英

使用LINQ获取一个List <>中的项目,而另一个List <>中的项目

[英]Use LINQ to get items in one List<>, that are in another List<>

我会假设有一个简单的LINQ查询可以做到这一点,但我不确定该如何做。 请参见下面的代码段,该注释说明了我要执行的操作:

class Program
{
  static void Main(string[] args)
  {
    List<Person> peopleList1 = new List<Person>();
    peopleList1.Add(new Person() { ID = 1 });
    peopleList1.Add(new Person() { ID = 2 });
    peopleList1.Add(new Person() { ID = 3 });
    peopleList1.Add(new Person() { ID = 4});
    peopleList1.Add(new Person() { ID = 5});

    List<Person> peopleList2 = new List<Person>();
    peopleList2.Add(new Person() { ID = 1 });
    peopleList2.Add(new Person() { ID = 4});


    //I would like to perform a LINQ query to give me only
    //those people in 'peopleList1' that are in 'peopleList2'
    //this example should give me two people (ID = 1& ID = 4)
  }
}


  class Person
  {
     public int ID { get; set; }
  }

您可以使用Where来做到这一点:

var result = peopleList1.Where(p => peopleList2.Any(p2 => p2.ID == p.ID));

您还可以使用Intersectvar result = peopleList1.Intersect(peopleList2); ),但这需要您实现一个额外的IEqualityComparer<Person>或以两个具有相同实例的Person实例的方式重写PersonEqualsGetHashCode方法ID被认为是相等的。 否则, Intersect将执行引用相等。

var result = peopleList2.Where(p => peopleList1.Any(p2 => p2.ID == p.ID));

我会在ID上加入两个列表:

var inboth = from p1 in peopleList1
             join p2 in peopleList2
             on p1.ID equals p2.ID
             select p1;
List<Person> joinedList = inboth.ToList();

相关: 为什么LINQ JOIN比链接到WHERE这么快?

如果要覆盖Equals + GetHashCode ,则可以使用Intersect

List<Person> joinedList = peopleList1.Intersect(peopleList2).ToList();

或者您可以为Intersect提供自定义的IEqualityComparer<Person>

public class  PersonIdComparer: IEqualityComparer<Person>
{
    public bool Equals(Person x, Person y)
    {
        if(object.ReferenceEquals(x, y)) return true;
        if (x == null || y == null) return false;

        return x.ID == y.ID;
    }

    public int GetHashCode(Person obj)
    {
        return obj == null ? int.MinValue : obj.ID;
    }
}

现在,您可以通过以下方式使用它:

List<Person> joinedList = peopleList1
     .Intersect(peopleList2, new PersonIdComparer())
     .ToList();

因为Enumerable.JoinEnumerable.Intersect都使用集合,所以它们都是有效的。

Product[] fruits1 = { new Product { Name = "apple", Code = 9 }, 
                           new Product { Name = "orange", Code = 4 },
                            new Product { Name = "lemon", Code = 12 } };

    Product[] fruits2 = { new Product { Name = "apple", Code = 9 } };

    //Get all the elements from the first array
    //except for the elements from the second array.

    IEnumerable<Product> except =
        fruits1.Except(fruits2);

    foreach (var product in except)
        Console.WriteLine(product.Name + " " + product.Code);

    /*
      This code produces the following output:

      orange 4
      lemon 12
    */

您可以使用Enumerable.Intersect

var common = peopleList1.Intersect(peopleList2);

您只可以使用LINQ相交扩展方法。

http://msdn.microsoft.com/zh-CN/library/bb460136(v=VS.100).aspx

因此,您可以这样:

class Program
{
  static void Main(string[] args)
  {
    List<Person> peopleList1 = new List<Person>();
    peopleList1.Add(new Person() { ID = 1 });
    peopleList1.Add(new Person() { ID = 2 });
    peopleList1.Add(new Person() { ID = 3 });
    peopleList1.Add(new Person() { ID = 4});
    peopleList1.Add(new Person() { ID = 5});

    List<Person> peopleList2 = new List<Person>();
    peopleList2.Add(new Person() { ID = 1 });
    peopleList2.Add(new Person() { ID = 4});

    var result = peopleList1.Intersect(peopleList2);
  }
}

只需覆盖Person-Class中的Equals方法。 我认为您可以在那里比较ID。

暂无
暂无

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

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