2012-02-02 72 views
0

我需要帮助找到最有效的方式来合并两个内存集合与LINQ到对象。在我的情况下,它不是简单的连接或concat,因为某些项目需要根据属性值排除。有条件地合并两个集合与LINQ到对象

让我们用下面的例子(不是很现实,但它说明了什么,我需要):

public abstract class Person 
{ 
    public String Name { get; set; } 
} 

public class Employee : Person 
{ 
    public DateTime? TerminationDate { get; set; } 
} 

public class Customer : Person 
{ 
    ... 
} 

注意,员工也可以是客户。

我公司员工的名单和客户的列表,并希望生成以下规则的所有人员的名单:

  1. 中未出现员工
  2. 所有员工是不是也所有客户客户并没有终止(TerminationDate == NULL)
  3. 所有的人是客户和员工,而不是终止(TerminationDate == NULL)

瓦以最有效的方式来完成这一点?

+1

一位顾客不能是雇员,无论如何,因为它们是不同的类。你的意思是“排除任何**与雇员同名**的顾客”吗? – 2012-02-02 15:59:41

+0

由于人员显然可以既是员工又是客户,同时继承可能不是建模对象最合适的方式。在这种情况下,我希望组合优于继承。 – 2012-02-02 15:59:49

+0

是的,当我说雇员也可能是客户时,我的意思是在现实世界中而不是客体。对困惑感到抱歉。 – SonOfPirate 2012-02-02 16:52:00

回答

0

虽然这不一定是错误的,但詹姆斯的例子有点复杂,我希望并且不完整,因为我需要一个列表作为最终结果。

不知道这是最好的解决办法,要么,但这里是我想出了迄今:

public abstract class Person 
{ 
    public String Name { get; set; } 

    public override Boolean Equals(Object other) 
    { 
     var otherPerson = other as Person; 

     if (otherPerson == null) 
      return false; 

     return Name.Equals(otherPerson.Name, StringComparison.OrdinalIgnoreCase); 
    } 
} 

public class Employee : Person 
{ 
    public DateTime? TerminationDate { get; set; } 
} 

public class Customer : Person 
{ 
    ... 
} 


public class People 
{ 
    private IEnumerable<Customer> Customers; 
    private IEnumerable<Employee> Employees; 

    public IEnumerable<Person> GetCurrentPeople() 
    { 
     // Find all customers that are not employees 
     var onlyCustomers = Customers.Except(Employees); 

     // We only want employees that have not been terminated 
     var currentEmployees = Employees.Where(e => e.TerminationDate == null); 

     // Find all customers that are also employees 
     var customerAndEmployees = currentEmployees.Intersect(Customers); 

     // Now deal with employees that are not customers 
     var onlyEmployees = currentEmployees.Except(Customers); 

     // Join the lists together 
     var mergedRules = onlyCustomers.Concat(onlyEmployees).Concat(customerAndEmployees); 

     return mergedRules; 
    } 
} 
0

很难说清楚,但假设Jon对名称匹配的猜测是正确的,那么这是否意味着概念上的意义?

请注意,它目前进行多次迭代,因此通常会在某些地方添加ToArray等,但我不想在验证概念位时将其添加到此代码中。

var allPeople = ...; 

var customers = allPeople.OfType<Customer>(); 
var employees = allPeople.OfType<Employee>(); 

var employeeNames = new HashSet(employees.Select(p => p.Name)); 
var customerNames = new HashSet(employees.Select(p => p.Name)); 

// list item #1 
var customersNotEmployees = customers 
    .Where(c => employeeNames.Contains(c.Name) == false); 

// will be used by #2 and #3 
var employeesNotTerminated = employees 
    .Where(e => e.TerminationDate == null); 

// list item #2 
var employeesNotCustomersAndNotTerminated = employeesNotTerminated 
    .Where(e => customerNames.Contains(e.Name) == false); 

// list item #3 
var employeesAndCustomersAndNotTerminated = employeesNotTerminated 
    .Where(e => customerNames.Contains(e.Name) == true);