比较两个列表与foreach循环,并从未找到的项目创建新的列表
本文关键字:列表 项目 创建 循环 两个 比较 foreach | 更新日期: 2023-09-27 18:01:36
很抱歉发了这么一个看似简单的问题。我知道有很多类似的问题已经发布了(在发布我的问题之前我已经看过其中的许多问题),但我很难将答案应用到我的情况中。我对c#比较陌生,非常感谢您的输入和帮助。
我如何比较我的2个Lists
和foreach
循环,并创建一个新的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);
}
提前感谢!
您可以使用Linq
的Except
扩展方法:
holidayDifference = remoteHolidays
.Except(localHolidays)
.ToList();
注意,这也需要Holiday
实现一个有效的Equals method of IEquatable<Holiday>
方法覆盖,而且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);
输出:
2
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));
}
}
输出:
光明节
最简单的方法是使用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
,它允许您将对象与函数/lambda表达式进行比较。
假设您有一个Equals
方法的重载并且Holiday
对象是可比较的
List<Holiday> holidayDifference = remoteHolidays.Except(localHolidays).ToList();
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);
}
如果您坚持foreach循环,您可以使用HashSet<Holiday>
来存储Holiday
s以排除:
HashSet<Holiday> hs = new HashSet<Holiday>(localHoliday);
foreach (Holiday holiday in remoteHolidays)
if (!hs.Contains(holiday))
holidayDifference.Add(holiday);
这取决于两个列表是否包含相同的Holiday对象,如果它们在两个列表中是相同的对象,那么你不需要制作一个实现IEqualityComparer的比较器。我将假设它们不是相同的对象,因此您是按值而不是按引用进行比较。
最快的方法是不使用foreach循环,您可以使用LINQ来完成此操作。
var holidayDifference = remoteHolidays.Except(localHolidays, new HolidaysComparer()).ToList();
如果你想使用foreach循环,你可以通过几种方式来实现。您可以使用HashSet(确保使用HolidayComparer初始化集合),通过迭代localHolidays中的值并将它们添加到集合中,然后从remoteHolidays中取出不在该集合中的值。然而,更简单的方法是使用LINQ的contains函数(上面的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