我有List<>
个自定义对象。此自定义类型具有名为Name
的属性,该属性在列表中应该是唯一的。换句话说,列表中没有2个项目的Name
属性应该具有相同的值。
当我验证此列表时,我想检索有问题的项目。是否有Linq操作允许我这样做?
我想要像
这样的东西listOfItems.Where(x => x.Name.Equals(/*anything else in this list with the same value for name */)
基本上,我试图避免针对列表中的每个项目(在嵌套的foreach中)检查整个列表:
private IList<ICustomObject> GetDuplicatedTypeNames(IList<ICustomObjects> customObjectsToFindDuplicatesIn)
{
var duplicatedList = new List<ICustomObject>();
foreach(var customObject in customObjectsToFindDuplicatesIn)
foreach(var innerCustomObject in customObjectsToFindDuplicatesIn)
if (customObject == innerCustomObject && customObject .Name.Equals(innerCustomObject.Name))
duplicatedList.Add(customObject);
return duplicatedList;
}
(编辑)注意:我被限制使用List&lt;&gt;通过域规则并使用字典&lt;&gt;不是一种选择。
答案 0 :(得分:8)
获取重复的名称:
var duplicates = listOfItems
.GroupBy(i => i.Name)
.Where(g => g.Count() > 1)
.Select(g => g.Key);
修改:获取重复的项目:
var duplicates = listOfItems
.GroupBy(i => i.Name)
.Where(g => g.Count() > 1)
.SelectMany(g => g);
答案 1 :(得分:3)
为什么不使用Dictionary而不是List,Name属性作为Key?这样,您根本不能add重复集合的名称,因为会抛出异常。
此外,在添加名称之前,您可以使用ContainsKey方法测试名称是否已在词典中。
这种方法的优点是它比扫描列表重复快得多。
答案 2 :(得分:0)
这将返回一个对象列表
class foo
{
public string Name { get; set; }
public override string ToString()
{
return Name;
}
}
class fooEqualityComparer : IEqualityComparer<foo>
{
public bool Equals(foo x, foo y)
{
if (x == null || y == null)
return false;
return x.Name == y.Name;
}
public int GetHashCode(foo obj)
{
return obj.Name.GetHashCode();
}
}
var duplicates = listOfItems
.GroupBy(x => x, new fooEqualityComparer())
.Where(g => g.Count() > 1)
.SelectMany(g => g);