C# 在C中是否有类似于alist的Addrange()的AddUnique方法#

C# 在C中是否有类似于alist的Addrange()的AddUnique方法#,c#,collections,unique,C#,Collections,Unique,我有一张C的清单: var list=newlist(); list.AddRange(GetGreenCars()); list.AddRange(GetBigCars()); list.AddRange(GetSmallCars()); 问题是,一些相同的汽车会以不同的功能返回,我不希望它们在列表中出现多次。每辆车都有一个唯一的名称属性。是否仍有类似于上述内容的内容,但仅在项目唯一的情况下添加项目?一种选择是添加项目并删除重复的项目: var list = new List<Car&

我有一张C的清单:

var list=newlist();
list.AddRange(GetGreenCars());
list.AddRange(GetBigCars());
list.AddRange(GetSmallCars());

问题是,一些相同的汽车会以不同的功能返回,我不希望它们在列表中出现多次。每辆车都有一个唯一的名称属性。是否仍有类似于上述内容的内容,但仅在项目唯一的情况下添加项目?

一种选择是添加项目并删除重复的项目:

var list = new List<Car>();
list.AddRange(GetGreenCars());
list.AddRange(GetBigCars());
list.AddRange(GetSmallCars());
list = list.Distinct().ToList();
var list=newlist();
list.AddRange(GetGreenCars());
list.AddRange(GetBigCars());
list.AddRange(GetSmallCars());
list=list.Distinct().ToList();
A
列表
似乎不是这里合适的集合。您可能需要一个
ISet
实现,例如(或者如果您需要订购)


为此,您需要编写一个
IEqualityComparer
实现,该实现根据
Name
属性定义汽车之间的平等性。如果这是汽车等式的“规范”定义,您也可以考虑将这个定义直接构造成<代码> CAL/<代码>类型本身(<代码>对象,等于,<代码>对象。GetHashCode < /代码>,并且理想地实现<代码> IEQuabtI/<代码>。

另一个选择是做一些类似的事情:

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());
publicstaticvoidaddunique(此IList自身,IEnumerable项)
{
foreach(项目中的var项目)
如果(!self.Contains(项目))
自我添加(项目);
}
var list=新列表();
list.AddUnique(GetGreenCars());
AddUnique(GetBigCars());
list.AddUnique(GetSmallCars());

使用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());
publicstaticvoidaddunique(此IList自身,IEnumerable项)
{
self.AddRange(
items.Where(x=>self.FirstOrDefault(y=>y.Name==x.Name)==
null.ToList());
}
var list=新列表();
list.AddUnique(GetGreenCars());
AddUnique(GetBigCars());
list.AddUnique(GetSmallCars());

如果您覆盖
汽车的
.Equals()
方法,以确定一个汽车对象与另一个汽车对象相同,则在不编写扩展方法的情况下,以下操作应该有效

var list=newlist();
list.AddRange(GetGreenCars()?。除了(list)?新列表());
list.AddRange(GetBigCars()?。除了(list)?新列表());
list.AddRange(GetSmallCars()?。除了(list)?新列表());

我创建了一个扩展方法,该方法只向从
IEnumerable
实现
ICollection
(包括
列表)的任何内容添加唯一值。与使用
List.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);
    }
}
//
///仅添加源中不存在的项。对于大型集合和某些类型的源,速度可能非常慢。
/// 
///在集合中键入。
///源集合
///谓词以确定新项是否已在源中。
///新项目。
公共静态void AddUniqueBy(此ICollection源、Func谓词、IEnumerable项)
{
foreach(项目中的T项目)
{
bool existsInSource=source.Where(s=>predicate(s,item)).Any();
如果(!existsInSource)source.Add(item);
}
}
用法:

source.AddUniqueBy<Foo>((s, i) => s.Id == i.Id, items);
source.AddUniqueBy((s,i)=>s.Id==i.Id,items);

如果您想比较一个属性(在本例中为id),这应该可以

var list = new List<string>();
list.AddRange(GetGreenCars().Where(greencar => !list.Contains(greencar, car => car.id == greencar.id)));
list.AddRange(GetBigCars().Where(bigcar => !list.Contains(bigcar, car => car.id == bigcar.id)));
list.AddRange(GetSmallCars().Where(smallcar => !list.Contains(smallcar, car => car.id == smallcar.id)));
var list=newlist();
list.AddRange(GetGreenCars().Where(greencar=>!list.Contains(greencar,car=>car.id==greencar.id));
list.AddRange(GetBigCars().Where(bigcar=>!list.Contains(bigcar,car=>car.id==bigcar.id));
list.AddRange(GetSmallCars().Where(smallcar=>!list.Contains(smallcar,car=>car.id==smallcar.id));

无Linq选项 如果程序员不能或不想使用Linq,则可以使用不同的选项

var list = new List<Car>();
list.AddRange(GetGreenCars().FindAll((x) => !list.Contains(x)));
list.AddRange(GetBigCars().FindAll((x) => !list.Contains(x)));
list.AddRange(GetSmallCars().FindAll((x) => !list.Contains(x)));
var list=newlist();
list.AddRange(GetGreenCars().FindAll((x)=>!list.Contains(x));
list.AddRange(GetBigCars().FindAll((x)=>!list.Contains(x));
list.AddRange(GetSmallCars().FindAll((x)=>!list.Contains(x));
如果初始列表如上例中所示为空,您实际上可以避免在第一个AddRange()上使用FindAll(…)。

假设您的Get*Cars()返回汽车列表,另一个选项可以是:

var list = new List<Car>();
GetGreenCars().ForEach(c => { if (!list.Contains(c)) list.Add(c); });
GetBigCars().ForEach(c => { if (!list.Contains(c)) list.Add(c); });
GetSmallCars().ForEach(c => { if (!list.Contains(c)) list.Add(c); });
var list=newlist();
GetGreenCars().ForEach(c=>{if(!list.Contains(c))list.Add(c);});
GetBigCars().ForEach(c=>{if(!list.Contains(c))list.Add(c);});
GetSmallCars().ForEach(c=>{if(!list.Contains(c))list.Add(c);});

我的收藏中有重复的对象。简单列表=list.Distinct().ToList();不起作用。Distinct将删除重复的对象。如果对象实际上不相同,则必须使对象实现Equals()和GetHashCode()。这是使用简单列表(如整数列表)进行操作的最佳方法。最佳简单思想不要忘记在Car上重写Equals()和GetHashCode(),否则它实际上与Contains()中的对象不匹配。否则,就是最好的答案。您也可以这样做来比较对象内的特定ID:vm.SearchResults.AddRange(searchResultsOr.Where(listOr=>!searchResultsAnd.Select(listAnd=>listAnd.PostId).Contains(listOr.PostId));你可以把它缩短一点:
GetGreenCars()。除了(list)
这对我很有帮助。这只能在原语上可靠地工作。对于复合类型,您必须能够提供一个比较函数,而不需要在何处和任何位置使用daisychain。只需将func传递给Any方法。
var list = new List<Car>();
GetGreenCars().ForEach(c => { if (!list.Contains(c)) list.Add(c); });
GetBigCars().ForEach(c => { if (!list.Contains(c)) list.Add(c); });
GetSmallCars().ForEach(c => { if (!list.Contains(c)) list.Add(c); });