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

Asked
Viewd295

1

我有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 <>,而不能使用Dictionary <>。

  • 似乎您的原始循环中有错误。它应该显示为:if(customObject!= innerCustomObject &&…)

    NescioNovember 13, 2009 12:27

3 个答案

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);
 
  • 这只会返回重复项的名称。

    NescioNovember 13, 2009 12:22
3

为什么不使用字典而不是列表,而将Name属性作为键?这样,您就不能重复名称添加到集合中,网址为全部,将引发异常。

此外,您可以使用 ContainsKey 方法来测试是否添加名称之前,词典中已经有一个名称。

这种方法的优势在于,它比扫描列表中的重复项要快得多。

  • 足够公平,我不知道您的情况不允许使用“字典”。.但是您应该在问题中对此进行指定。

    Jean AzzopardiNovember 13, 2009 15:00
  • 从描述中,在我看来,有一个List允许骗人,而询问者想知道这些骗子是什么

    AbelNovember 13, 2009 11:40
  • “我的列表”是可视网格的后端数据源。用户在网格中编辑值,并且我希望即时进行验证。词典将不必要地使数据源复杂化。另外,由于领域模型的工作原理,我也受到该规则的限制。

    CorpsekickerNovember 13, 2009 11:39
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);