部分不同的 Linq

Sve*_*dos 3 c# linq

我有一个对象列表。这些对象有一个属性,例如“值”。

       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);
Run Code Online (Sandbox Code Playgroud)

我想这样说:

lst.PartialDistinct(x => x.Value == "A")
Run Code Online (Sandbox Code Playgroud)

这应该仅通过谓词来区分,并且在打印结果 IEnumerable 的“值”时,结果应该是:

A
B
B
Run Code Online (Sandbox Code Playgroud)

我已经找到了 DistinctBy 的解决方案,可以在其中定义键选择器。但结果当然是:

A
B
Run Code Online (Sandbox Code Playgroud)

Cyral 的第一个答案完成了这项工作。所以我接受了。但 Scott 的回答确实是一个 PartialDistinct() 方法,看起来它解决了我所有的问题。

好吧,以为用 Scott 的解决方案解决了,但事实并非如此。也许我在单元测试时犯了一个错误……或者我不知道。问题是:

if(seen.Add(item)) 
Run Code Online (Sandbox Code Playgroud)

这不会过滤掉值为“A”的其他对象。我认为这是因为它在放入哈希集时依赖于引用相等性。

我最终得到了以下解决方案:

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)));
    }
Run Code Online (Sandbox Code Playgroud)

Gio*_*sos 5

您可以使用 进行分组Value并执行“条件展平” SelectMany,即仅从“A”组中获取一个元素,并从其余组中获取所有元素:

var result = lst.GroupBy(x => x.Value)
                .SelectMany(g => g.Key == "A" ? g.Take(1) : g);
Run Code Online (Sandbox Code Playgroud)