在 C# 中,IEnumerable 的 Union 方法用于返回两个序列的并集。Union 方法会去除重复的元素,确保结果集中每个元素都是唯一的。以下是 Union 方法的基本用法:
基本语法
public static IEnumerable<TSource> Union<TSource>(this IEnumerable<TSource> first, IEnumerable<TSource> second);
public static IEnumerable<TSource> Union<TSource>(this IEnumerable<TSource> first, IEnumerable<TSource> second, IEqualityComparer<TSource>? comparer);
参数说明
- first: 第一个序列。
- second: 第二个序列。
- comparer:自定义比较器
示例
简单示例
假设我们有两个整数集合,我们希望将它们合并成一个集合,并去除重复的元素。
var list1 = new List<int> { 1, 2, 3, 4, 5 };
var list2 = new List<int> { 4, 5, 6, 7, 8 };
使用 Union 方法
var unionList = list1.Union(list2);
foreach (var item in unionList)
{
Console.WriteLine(item);
}
输出
1
2
3
4
5
6
7
8
在这个示例中,Union 方法将 list1 和 list2 合并成一个新的集合 unionList,并且去除了重复的元素 4 和 5。
自定义类型
如果你有一个自定义类型,你可以通过重写 Equals 和 GetHashCode 方法来确保 Union 方法正确地识别重复元素。
定义示例类
定义一个Person类,有ID和Name,我们定义只有Id和Name都相同才表示是相同
public class Person
{
public int Id { get; set; }
public string Name { get; set; }
public override bool Equals(object obj)
{
if (obj is Person other)
{
return Id == other.Id && Name == other.Name;
}
return false;
}
public override int GetHashCode()
{
return HashCode.Combine(Id, Name);
}
}
测试数据
var people1 = new List<Person>
{
new Person { Id = 1, Name = "丁一" },
new Person { Id = 2, Name = "王二" },
};
var people2 = new List<Person>
{
new Person { Id = 2, Name = "王二" },
new Person { Id = 3, Name = "张三" },
};
使用 Union 方法
使用Union
进行并集操作
var unionPeople = people1.Union(people2);
foreach (var person in unionPeople)
{
Console.WriteLine($"Id: {person.Id}, Name: {person.Name}");
}
输出
可以看到过滤到了里面的重复对象
测试数据2
var people1 = new List<Person>
{
new Person { Id = 1, Name = "丁一" },
new Person { Id = 2, Name = "王二" },
};
var people2 = new List<Person>
{
new Person { Id = 2, Name = "王二1" },
new Person { Id = 3, Name = "张三" },
};
测试结果
可以看到名字不相同就没有过滤
注意事项
• Union
方法默认使用元素的 Equals
和 GetHashCode
方法来比较元素。
• 如果你需要自定义比较逻辑,可以使用 Union
的重载方法,该方法接受一个 IEqualityComparer 参数。
使用自定义比较器
在这个示例中,我们使用了一个自定义的 PersonComparer 来比较 Person 对象,确保 Union 方法根据 Id 进行比较。
使用自定义比较器进行 Union,创建一个自定义比较器PersonComparer
来比较,里面以Id为基准
public class PersonComparer : IEqualityComparer<Person>
{
public bool Equals(Person x, Person y)
{
if (x is null && y is null) return true;
if (x is null || y is null) return false;
return x.Id == y.Id;
}
public int GetHashCode(Person obj)
{
return obj.Id.GetHashCode();
}
}
然后使用Union进行比较
var customComparer = new PersonComparer();
var unionPeopleCustom = people1.Union(people2, customComparer);
foreach (var person in unionPeopleCustom)
{
Console.WriteLine($"Id: {person.Id}, Name: {person.Name}");
}
结果
根据比较器,只根据Id进行了过滤