是否有Linq操作从项目列表中检索特定项目,其中项目具有应该是唯一的属性的属性值?

时间:2009-11-13 11:28:35

标签: c# linq

我有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;不是一种选择。

3 个答案:

答案 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);