Concat两个List <t>,其中每个中的字段值相等</t>

时间:2014-01-26 16:35:12

标签: c# linq lambda

class Person
{
    public String FirstName { get; set; }
    public String LastName { get; set; }

    public Person(String firstName String lastName)
    {
        FirstName = firstName 
        LastName = lastName;
    }
}

public static void Main()
{
    List<Person> males = new List<Person>();

    males.Add(new Person() {FirstName = "Fred", LastName = "Blogs"});
    males.Add(new Person() {FirstName = "John", LastName = "James"});
    males.Add(new Person() {FirstName = "Harry", LastName = "Adams"});
    males.Add(new Person() {FirstName = "Peter", LastName = "Blogs"});

    List<Person> females = new List<Person>();

    females.Add(new Person() {FirstName = "Mary", LastName = "Blogs"});
    females.Add(new Person() {FirstName = "Anne", LastName = "James"});
    females.Add(new Person() {FirstName = "Jane", LastName = "Doe"});

    List<Person> results = new List<Person>();

    results = males.Concat(females)...; // This is where I stumble ??
}

List<Person> results需要包含两个列表中都存在males.LastNamefemales.LastName的所有行。

即。 List<Person> results应包含...

    FirstName = "Fred", LastName = "Blogs"});
    FirstName = "John", LastName = "James"});
    FirstName = "Peter", LastName = "Blogs"});
    FirstName = "Mary", LastName = "Blogs"});
    FirstName = "Anne", LastName = "James"});

注意:应排除 Harry Adams Jane Doe ,因为他们的姓氏不在两个列表中。

(换句话说,如果我最喜欢的啤酒公司统治这个世界,我需要这样的东西:

`results = males.Concat(female).Where(males.LastName == female.LastName);`

它会弄清楚......啊!如果只是)

任何帮助都将不胜感激。

2 个答案:

答案 0 :(得分:4)

var result = males.Concat(females).Where(p => males.Any(x => p.LastName == x.LastName) && 
                                             females.Any(x => p.LastName == x.LastName))
                                 .ToList();

以下是提供预期结果的完整代码:

[Test]
public void LINQTest()
{
     List<Person> males = new List<Person>();

     males.Add(new Person() { FirstName = "Fred", LastName = "Blogs" });
     males.Add(new Person() { FirstName = "John", LastName = "James" });
     males.Add(new Person() { FirstName = "Harry", LastName = "Adams" });
     males.Add(new Person() { FirstName = "Peter", LastName = "Blogs" });

     List<Person> females = new List<Person>();

     females.Add(new Person() { FirstName = "Mary", LastName = "Blogs" });
     females.Add(new Person() { FirstName = "Anne", LastName = "James" });
     females.Add(new Person() { FirstName = "Jane", LastName = "Doe" });

     List<Person> results = new List<Person>();

     var result = males.Concat(females).Where(p => males.Any(x => p.LastName == x.LastName) &&
                                                   females.Any(x => p.LastName == x.LastName))
                                       .ToList();

        Assert.AreEqual(result.Count, 5); // true
}

或者你可以像这样使用Intersect和Contains,它可能会快得多。

 var names = males.Select(p => p.LastName)
                  .Intersect(females.Select(p => p.LastName))
                  .ToList();
var result = males.Concat(females)
                    .Where(p =>names.Contains(p.LastName))
                    .ToList();

答案 1 :(得分:2)

如果有很多人,你需要它便宜,以测试一个人是否被保留(即有一个共同的名字)或被丢弃。您可以通过预先创建HashSet来执行此操作:

var allMaleLastNames = males.Select(m => m.LastName);
var allFemaleLastNames = females.Select(f => f.LastName);

var uniqueSharedLastNames = new HashSet<string>(
    allMaleLastNames.Intersect(allFemaleLastNames));

var result = males.Concat(females)
    .Where(p => uniqueSharedLastNames.Contains(p.LastName));