2012-02-02 71 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);