我有一个对象列表。这些对象有一个属性,例如“值”。
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)
您可以使用 进行分组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)