简体   繁体   中英

How to select distinct items from a list

I have this class

class Test
    {
        public string Property { get; set; }
        public string ID { get; set; }
        public List<string> MyProperty { get; set; } 

    }

and I create a instance of it

 List<Test> t = new List<Test>() {
                new Test() {
                     ID = "1",
                      Property = "2"

                },
                new Test() {
                     ID = "2",
                      Property = "3"
                },
                new Test() {
                     ID = "2",
                     Property = "5"
                }

            };

I want to have a List which has distinct elements filteried by ID and also the public List MyProperty { get; set; } should be filled with public string Property { get; set; } data.

So the final result should be

List<Test> = {
   1.   ID = "1",List<MyProperty> = "2"
   2.   ID = "2",List<MyProperty> = "2"                        

};

You can use GroupBy and First to remove duplicates:

t.GroupBy(x => x.Id)
    .Select(g => g.First())
    .ToList();
t.Distinct(new TestComparer());

Where TestComparer is your comparer's implementation. Here's the sample

// Custom comparer for the Test class
class ProductComparer : IEqualityComparer<Test>
{
    // Tests are equal if their IDs are equal.
    public bool Equals(Test x, Test y)
    {
        //Check whether the compared objects reference the same data.
        if (Object.ReferenceEquals(x, y)) return true;

        //Check whether any of the compared objects is null.
        if (Object.ReferenceEquals(x, null) || Object.ReferenceEquals(y, null))
            return false;

        //Check whether the products' properties are equal.
        return x.Id == y.Id;
    }

    // If Equals() returns true for a pair of objects 
    // then GetHashCode() must return the same value for these objects.

    public int GetHashCode(Test test)
    {
        //Check whether the object is null
        if (Object.ReferenceEquals(test, null)) return 0;

        //Get hash code for the Name field if it is not null.
        int hashId = test.Id == null ? 0 : test.Id.GetHashCode();

        //Calculate the hash code for the test.
        return hashId;

        //Should be enough, but you can merge hashcodes of other fields in some way, for example:
        //int hashProperty = test.Property == null ? 0 : test.Property.GetHashCode();
        //return hashId ^ hashProperty;
    }
}

I would use the GroupBy() LINQ extensions:

t.GroupBy(x => x.ID)
 .Select(x => new Test {
    ID = x.Key,
    MyProperty = x.Select(y => y.Property).ToList()
 })
 .ToList();

Where the param of GroupBy is the key you want to group over, so ID in your case.

The Select will then project them into the new Test

Here are some useful links:

https://msdn.microsoft.com/en-us/library/bb545971.aspx

https://msdn.microsoft.com/en-us/library/bb534304(v=vs.110).aspx

The result will be:

[
    {
        "ID": "1",
        "MyProperty": [ "2" ],
        "Property": null
    },
    {
        "ID": "2",
        "MyProperty": [ "3", "5" ],
        "Property": null
    },
]

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