2016-08-10 70 views
1

對於發佈這樣一個看似簡單的問題,我表示抱歉。我知道已經發布了很多類似的問題(在發佈我的問題之前我已經看過很多這類問題),但我很難將答案應用於我的情況。我對C#相對來說比較陌生,並且非常感謝您的意見和幫助。將2個列表與一個foreach循環進行比較,並從未找到的項目創建新列表

如何將我的2 Listsforeach循環進行比較,並創建一個新的List,並在我的比較中找到不存在的記錄?

下面是代碼大綱我已經有,和我們需要的意見發生:

private void updateHolidays() 
{ 
    List<Holiday> localHolidays = getLocalHolidays(); 
    List<Holiday> remoteHolidays = getRemoteHolidays(); 

    List<Holiday> holidayDifference = new List<Holiday>(); 

    foreach (Holiday holiday in remoteHolidays) 
    { 
     if (true) // holiday does not exist in localHolidays 
     { 
      // add holiday to holidayDifference 
      holidayDifference.Add(holiday); 
     } 
    } 

    createNewHolidays(holidayDifference); 
} 

預先感謝您!

+1

爲什麼要求'foreach'循環? – Aphelion

+0

可能的重複http://stackoverflow.com/questions/806152/is-there-a-way-to-get-the-difference-between-two-sets-of-objects-in-c-sharp? –

回答

2

最簡單的方法就是使用LinQ。 Except方法返回源中不存在於第二個列表中的所有項目。

holidayDifference = remoteHolidays.Except(localHolidays).ToList(); 

Except方法接受可選的第二個參數來自定義比較。如果您未通過IEqualityComparer<T>,則將使用與Holiday.Equals方法的標準比較。或者,您可以重寫此方法而不是傳遞比較器。

與大多數LinQ方法一樣,Except返回IEnumerable<T>,這可以通過ToList方法輕鬆轉換爲List<T>

MSDN文檔是內聯鏈接的。


如果你還是想自己實現,你可以使用的List<T>Contains方法:

foreach (Holiday holiday in remoteHolidays) 
{ 
    if (!localHolidays.Contains(holidy)) 
    { 

Contains另一種方法是LinQs Any它允許您將對象與功能比較/ lamda表達。

2

假設你有Equals方法和Holiday對象的過載是compareable

List<Holiday> holidayDifference = remoteHolidays.Except(localHolidays).ToList(); 
2

您可以使用LinqExcept擴展方法:

holidayDifference = remoteHolidays 
    .Except(localHolidays) 
    .ToList(); 

注意,這將還需要Holiday實施有效的Equals method of IEquatable<Holiday>方法o verride,也GetHashCode必須返回一個相同的散列兩個Holidays其中Equals返回true

此外,Except是返回(在這種情況下)的IEnumerable<Holiday>因此你將不得不使用ToList擴展方法,以檢索List<Holiday>

備選地延伸,則可以使用other overload of Except它允許你提供一個IEqualityComparer<Holiday>而不是修改您的原始類。


strings實施例:

List<string> holidayDifference = new List<string>(); 
List<string> remoteHolidays = new List<string> { "1", "2", "3" }; 
List<string> localHolidays = new List<string> { "1", "3" }; 
holidayDifference = remoteHolidays 
    .Except(localHolidays) 
    .ToList(); 
holidayDifference.ForEach(Console.WriteLine); 

輸出:


實施例隨着Holiday : IEquatable<Holiday>

class Holiday : IEquatable<Holiday> 
{ 
    public string Name { get; set; } 

    public bool Equals(Holiday other) 
    { 
     return Name == other.Name; 
    } 

    // GetHashCode must return true whenever Equals returns true. 
    public override int GetHashCode() 
    { 
     //Get hash code for the Name field if it is not null. 
     return Name?.GetHashCode() ?? 0; 
    } 
} 

public class Program 
{ 
    public static void Main() 
    { 
     List<Holiday> holidayDifference = new List<Holiday>(); 
     List<Holiday> remoteHolidays = new List<Holiday> 
     { 
      new Holiday { Name = "Xmas" }, 
      new Holiday { Name = "Hanukkah" }, 
      new Holiday { Name = "Ramadan" } 
     }; 
     List<Holiday> localHolidays = new List<Holiday> 
     { 
      new Holiday { Name = "Xmas" }, 
      new Holiday { Name = "Ramadan" } 
     }; 
     holidayDifference = remoteHolidays 
      .Except(localHolidays) 
      .ToList(); 
     holidayDifference.ForEach(x => Console.WriteLine(x.Name)); 
    } 
} 

輸出:

光明

0

如果你堅持的foreach循環中,您可以使用HashSet<Holiday>存儲Holiday s到排除:

HashSet<Holiday> hs = new HashSet<Holiday>(localHoliday); 

foreach (Holiday holiday in remoteHolidays) 
    if (!hs.Contains(holiday)) 
    holidayDifference.Add(holiday); 
0
private void updateHolidays() 
{ 
    List<Holiday> localHolidays = getLocalHolidays(); 
    List<Holiday> remoteHolidays = getRemoteHolidays(); 

    List<Holiday> holidayDifference = new List<Holiday>(); 

    foreach (Holiday holiday in remoteHolidays)`` 
    { 
     if (localHolidays.Contains(holiday)) 
     { 
      // add holiday to holidayDifference 
      holidayDifference.Add(holiday); 
     } 
    } 

    createNewHolidays(holidayDifference); 
} 
0

這取決於如果兩個列表包含相同的假日對象,如果他們是在兩個列表中都有相同的對象,那麼您不需要創建一個實現IEqualityComparer的比較器。我會假設他們不是同一個對象,因此你正在通過價值而不是參考進行比較。

這樣做的最快方法是沒有foreach循環,你可以使用LINQ來做到這一點。

var holidayDifference = remoteHolidays.Except(localHolidays, new HolidaysComparer()).ToList(); 

如果你想使用foreach循環做到這一點,你可以通過幾種方式來完成。您可以使用HashSet(確保使用HolidayComparer初始化該集合)迭代localHolidays中的值並將它們添加到集合中,然後從遠程集合中取出那些不在該集合中的集合。然而,簡單的方法是使用LINQ包含函數(上面的except函數基本上將它包裝到一個循環中)。

var holidayDifference = new List<Holiday>(); 
var comparer = new HolidayComparer(); 
foreach(Holiday holiday in remoteHolidays) 
{ 
    if(!localHolidays.Contains(holiday, comparer)) 
     holidayDifference.Add(holiday); 
} 

如果您通過引用來比較每個節假日,那麼您將不需要實現IEqualityComparer接口。

要了解如何實現此界面,請看這裏IEqualityComparer Interface

相關問題