English 中文(简体)
Is there a Linq operation to retrieve specific items from a list of items where the item has a property value for a property which should be unique?
原标题:
  • 时间:2009-11-13 11:28:35
  •  标签:
  • c#
  • linq

I have a List<> of custom objects. This custom type has a property called Name which should be unique among the list. In other words, no 2 items items in the list should have the same value for their Name property.

When I validate this list, I want to retrieve the offending items. Is there a Linq operation which will allow me to do this?

I want to have something like

listOfItems.Where(x => x.Name.Equals(/*anything else in this list with the same value for name */)

Basically, I am trying to avoid checking the entire list against every item in the list (in a nested 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;
    }

(EDIT) NOTE: I am constrained to using a List<> by domain rules and using a Dictionary<> is not an option.

最佳回答

Get names of duplicates:

 var duplicates = listOfItems
        .GroupBy(i => i.Name)
        .Where(g => g.Count() > 1)
        .Select(g => g.Key);

Edit: Get duplicate items:

var duplicates = listOfItems
    .GroupBy(i => i.Name)
    .Where(g => g.Count() > 1)
    .SelectMany(g => g);
问题回答

Why not use a Dictionary instead of a List then, with the Name property as the Key? That way, you can t add duplicate names to the collection at all, as an exception would be thrown.

Furthermore, you can use the ContainsKey method to test if a name is already in the Dictionary before adding it.

The advantage of this approach is that it s much faster than scanning the List for duplicates.

This will return a list of objects

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




相关问题
Anyone feel like passing it forward?

I m the only developer in my company, and am getting along well as an autodidact, but I know I m missing out on the education one gets from working with and having code reviewed by more senior devs. ...

NSArray s, Primitive types and Boxing Oh My!

I m pretty new to the Objective-C world and I have a long history with .net/C# so naturally I m inclined to use my C# wits. Now here s the question: I feel really inclined to create some type of ...

C# Marshal / Pinvoke CBitmap?

I cannot figure out how to marshal a C++ CBitmap to a C# Bitmap or Image class. My import looks like this: [DllImport(@"test.dll", CharSet = CharSet.Unicode)] public static extern IntPtr ...

How to Use Ghostscript DLL to convert PDF to PDF/A

How to user GhostScript DLL to convert PDF to PDF/A. I know I kind of have to call the exported function of gsdll32.dll whose name is gsapi_init_with_args, but how do i pass the right arguments? BTW, ...

Linqy no matchy

Maybe it s something I m doing wrong. I m just learning Linq because I m bored. And so far so good. I made a little program and it basically just outputs all matches (foreach) into a label control. ...

热门标签