Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Partial Distinct Linq

Tags:

c#

linq

I have a list of objects. These objects have a property e.g. "Value".

       var lst = new List<TestNode>();

       var c1 = new TestNode()
        {
          Value = "A",
        };

        lst.Add(c1);

        var c2 = new TestNode()
        {
            Value = "A",
        };

        lst.Add(c2);

        var c3 = new TestNode()
        {
            Value = "B",
         };

        lst.Add(c3);

        var c4 = new TestNode()
        {
             Value = "B",
        };

        lst.Add(c4);

I would like to say something like:

lst.PartialDistinct(x => x.Value == "A")

This should only be distinct by predicate and when printing the "Value"s of the resulting IEnumerable the result should be:

A
B
B

I already found solutions for DistinctBy where it's possible to define a Key-Selector. But the result is then of course:

A
B

Cyral's first answer did the job. So I accepted it. But Scott's answer is really a PartialDistinct() Method as asked and looks like it solves all my problems.

Ok, thought it's solved with Scott's solution but it's not. Maybe I made a mistake while unit testing... or I don't know. The problem is:

if(seen.Add(item)) 

This does not filter out other objects with value "A".I think this is because it relies on referential equality when putting into hashset.

I ended up with following solution:

public static IEnumerable<T> PartialDistinct<T>(this IEnumerable<T> source Func<T, bool> predicate)
    {
        return source
            .Where(predicate)
            .Take(1)
            .Concat(source.Where(x => !predicate(x)));
    }
like image 689
Sven Bardos Avatar asked Sep 14 '26 01:09

Sven Bardos


1 Answers

You can group by Value and perform 'conditional flattening' using SelectMany, i.e. take only one element from 'A' groups and all elements from the rest of the groups:

var result = lst.GroupBy(x => x.Value)
                .SelectMany(g => g.Key == "A" ? g.Take(1) : g);
like image 172
Giorgos Betsos Avatar answered Sep 15 '26 14:09

Giorgos Betsos



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!