我在C#中有一个具有一些属性的对象:
// Pseudo class
public class
{
Id;
To;
From;
}
我在Collection
中有很多类的实例。这看起来像这样:
object 1:
Id: 1
To: "PathA"
From: "PathB"
object 2:
Id: 2
To: "PathB"
From: "PathC"
object 3:
Id: 3
To: "PathC"
From: "PathA"
现在我要做的是获取该集合中的所有项目,其中To
的值未出现在任何对象的From
中。这将导致以下结果:
object 1:
Id: 1
To: "PathA"
From: "PathB"
object 2:
Id: 2
To: "PathB"
From: "PathC"
因为Id: 3
的最后一个对象在PathA
属性中有From
,该属性已存在于To
属性的某个位置。
如何使用Linq查询执行此操作?
答案 0 :(得分:2)
To
的所有值的索引。然后,根据From
属性... 过滤您的序列
类似的东西:
var tos = new HashSet<string>(collection.Select(item => item.To));
var filtered = collection.Where(item => !tos.Contains(item.From));
您可能想要检查一下,如果创建HashSet
确实是这样的,或者您需要以不同的方式构建它......但您明白了。如果tos
变得相当长,那么集合是有效的,因为你会经常检查这个...
答案 1 :(得分:1)
说出你的对象集合如下:
var objects = { object1, object2, object3 }
然后你想要:
var result = objects.Where(o => !objects.Select(x => x.From).Contains(o.To));
如果它涉及大型数据集,则缓存并存储“从”路径的子选择可能是明智的:
var fromPaths = new HashSet<string>(objects.Select(x => x.From));
var result = objects.Where(o => !fromPaths.Contains(o.To))
答案 2 :(得分:1)
首先,您的示例与问题文本不匹配,因为所有示例对象的To
都与其他From
对应。但假设问题文本是正确的,样本是错误的:
使用group-join:
怎么样?var query = from obj in collection
join fromObj in collection
on obj.To equals fromObj.From
into objGroup
where !objGroup.Any()
select obj;
或者,首先建立一组不同的Froms:
var distinctFroms = new HashSet<string>(collection.Select(item => item.From));
var query = from obj in collection
where !distinctFroms.Contains(obj.To)
select obj;
答案 3 :(得分:0)
var list = collection.Select(c=>c.To).Distinct().ToList();
var result = collection.Where(c=>!list.Contains(c.From)).ToList();
答案 4 :(得分:0)
如果您使用“收件人”和“收件人”作为相应的密钥将集合重新加入自身,则可以通过“收件人/来自”来确定哪些商品已“加入”并将其排除在外:
var itemsThatAreConnected =
collection.Join(collection, x => x.To, x => x.From, (a,b) => a);
var unconnected = collection.Except(itemsThatAreConnected);