使用LINQ获取一个List<>中的项目,这些项目位于另一个List<>中

时间:2016-05-23 10:51:42

标签: c# linq

我认为这是一个简单的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; }
  }

6 个答案:

答案 0 :(得分:4)

您可以使用Where

执行此操作
var result = peopleList1.Where(p => peopleList2.Any(p2 => p2.ID == p.ID));

您也可以使用Intersectvar result = peopleList1.Intersect(peopleList2);),但这需要您实施额外的IEqualityComparer<Person>或覆盖Person的{​​{1}}和{ {1}}方法使两个具有相同Equals的{​​{1}}个实例视为相等。否则GetHashCode将执行引用相等。

答案 1 :(得分:2)

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

答案 2 :(得分:2)

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

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

相关:Why is LINQ JOIN so much faster than linking with WHERE?

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

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

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

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都有效,因为他们使用的是一套。

答案 3 :(得分:1)

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
    */

答案 4 :(得分:1)

您可以使用Enumerable.Intersect

var common = peopleList1.Intersect(peopleList2);

答案 5 :(得分:0)

您可以使用LINQ Intersect Extension Method。

http://msdn.microsoft.com/en-us/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方法。我想你可以比较那里的ids。