简体   繁体   中英

C# - how to get distinct items from a Collection View

CollectionView view = CollectionView)CollectionViewSource.GetDefaultView(MyData);
View.Filter = i => ((MyClass)i).MyProperty;

I have a collection view like in the above. The problem is that the collection MyData which has already been bound to a listview contains duplicate items. How do I get unique items as the result of my filtering?

You can try this

var g = collection.Select(i => i.Property1).Distinct();

And please give a feedback, if it work.

Looks like I'm late while figuring out the best solution that fits your need. Anyway I'm providing it because it's cleaner and faster than the accepted.

First as usual let define a function that encapsulates the logic

static bool IsDuplicate(IEnumerable<MyObject> collection, MyObject target)
{
    foreach (var item in collection)
    {
        // NOTE: Check only the items BEFORE the one in question
        if (ReferenceEquals(item, target)) break;
        // Your criteria goes here
        if (item.MyProperty == target.MyProperty) return true;
    }
    return false;
}

and then use it

var view = (CollectionView)CollectionViewSource.GetDefaultView(MyData);
view.Filter = item => !IsDuplicate((IEnumerable<MyClass>)view.SourceCollection, (MyClass)item);

In addition to the answer from @Sebastian Tam

var g = collection.Select(i => i.Property1).Distinct();

If collection is a sequence from a User-defined class of your own, you need to implement IEquatable Interface for Distinct to use the default Comparer.

Have a look at this post

What is the default equality comparer for a set type?

This method works:

CollectionView view = (CollectionView)CollectionViewSource.GetDefaultView(c.Items);
view.Filter = i =>
{
    var index1 = c.MyData.FindIndex(delegate (MyClass s)
    {
        return Object.ReferenceEquals(s, i);
    });
    var index2 = c.MyData.FindLastIndex(delegate (MyClass s)
    {
        return ((MyClass)i).MyProperty == s.MyProperty as string; //value comparison
    });
    return index1 == index2;
};

index1 is the index of the object in the collection. You need to compare the references to get that.

index2 is the last index of the value . There you need to compare the value .

So you basically compare if the index of the current element is the last one where it occurs.

Note :

this does not work naturally with simple types. I had to initialize my test collection like this:

new List<string>() { new string("I1".ToCharArray()), new string("I1".ToCharArray()), "I2" };

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM