leo*_*ora 30 c# collections unique
我在C#中有一个列表:
var list = new List<Car>();
list.AddRange(GetGreenCars());
list.AddRange(GetBigCars());
list.AddRange(GetSmallCars());
Run Code Online (Sandbox Code Playgroud)
问题是一些相同的汽车在不同的功能中返回,我不希望它们在列表中不止一次.每辆车都有一个唯一的Name属性.无论如何我可以在上面有这样的东西,但只会添加项目,如果它们是独一无二的?
Ivo*_*Ivo 47
一种选择是添加它们并删除重复的:
var list = new List<Car>();
list.AddRange(GetGreenCars());
list.AddRange(GetBigCars());
list.AddRange(GetSmallCars());
list = list.Distinct().ToList();
Run Code Online (Sandbox Code Playgroud)
Ivo*_*Ivo 25
另一种选择是做类似的事情:
public static void AddUnique<T>( this IList<T> self, IEnumerable<T> items )
{
foreach(var item in items)
if(!self.Contains(item))
self.Add(item);
}
var list = new List<Car>();
list.AddUnique(GetGreenCars());
list.AddUnique(GetBigCars());
list.AddUnique(GetSmallCars());
Run Code Online (Sandbox Code Playgroud)
Ani*_*Ani 18
A List<T>似乎不是这里的合适集合.您可能想要一个ISet<T>实现,如HashSet<T>(或SortedSet<T>如果您需要订购).
为此,您需要编写一个IEqualityComparer<T>实现,根据Name属性定义汽车之间的相等性.如果这是汽车平等的"规范"的定义,你也可以直接考虑建设这个定义为Car类型本身(object.Equals,object.GetHashCode理想情况下实现IEquatable<T>过).
Jos*_*ust 11
给你覆盖.Equals()的方法Car来确定一个汽车对象是一样的另一辆汽车的对象,那么下面应该工作的W/O写的扩展方法.
var list = new List<Car>();
list.AddRange(GetGreenCars()?.Except(list) ?? new List<Car>());
list.AddRange(GetBigCars()?.Except(list) ?? new List<Car>());
list.AddRange(GetSmallCars()?.Except(list) ?? new List<Car>());
Run Code Online (Sandbox Code Playgroud)
使用Linq的另一个选择:
public static void AddUnique<T>(this IList<T> self, IEnumerable<T> items)
{
self.AddRange(
items.Where(x => self.FirstOrDefault(y => y.Name == x.Name) ==
null).ToList());
}
var list = new List<Car>();
list.AddUnique(GetGreenCars());
list.AddUnique(GetBigCars());
list.AddUnique(GetSmallCars());
Run Code Online (Sandbox Code Playgroud)
我创造了只添加唯一值的任何实现的扩展方法ICollection<T>(包括List<T>从)IEnumerable<T>。与使用 的实现不同List<T>.Contains(),此方法允许您指定一个 lambda 表达式来确定两个项目是否相同。
/// <summary>
/// Adds only items that do not exist in source. May be very slow for large collections and some types of source.
/// </summary>
/// <typeparam name="T">Type in the collection.</typeparam>
/// <param name="source">Source collection</param>
/// <param name="predicate">Predicate to determine whether a new item is already in source.</param>
/// <param name="items">New items.</param>
public static void AddUniqueBy<T>(this ICollection<T> source, Func<T, T, bool> predicate, IEnumerable<T> items)
{
foreach (T item in items)
{
bool existsInSource = source.Where(s => predicate(s, item)).Any();
if (!existsInSource) source.Add(item);
}
}
Run Code Online (Sandbox Code Playgroud)
用法:
source.AddUniqueBy<Foo>((s, i) => s.Id == i.Id, items);
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
30323 次 |
| 最近记录: |