C# 使用Linq从集合中获取对象
我在C中有一个对象,它有几个属性:C# 使用Linq从集合中获取对象,c#,.net,linq,C#,.net,Linq,我在C中有一个对象,它有几个属性: // Pseudo class public class { Id; To; From; } 我在一个集合中有很多该类的实例。可能是这样的: object 1: Id: 1 To: "PathA" From: "PathB" object 2: Id: 2 To: "PathB" From: "PathC" object 3: Id: 3 To: "PathC" From: "PathA" 现
// Pseudo class
public class
{
Id;
To;
From;
}
我在一个集合中有很多该类的实例。可能是这样的:
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的最后一个对象在From属性中具有PathA,该PathA已存在于To属性的某个位置
如何使用Linq查询实现这一点?那么,如何解决这个问题呢?首先,可以创建To的所有值的索引。然后,根据From属性筛选序列 比如:
var tos = new HashSet<string>(collection.Select(item => item.To));
var filtered = collection.Where(item => !tos.Contains(item.From));
您可能需要检查,创建哈希集是否真的像这样工作,或者是否需要以不同的方式构造它。。。但你明白了。集合是有效的,如果tos变得相当长,因为您将经常检查它…那么,如何解决这个问题呢?首先,可以创建To的所有值的索引。然后,根据From属性筛选序列
var list = collection.Select(c=>c.To).Distinct().ToList();
var result = collection.Where(c=>!list.Contains(c.From)).ToList();
比如:
var tos = new HashSet<string>(collection.Select(item => item.To));
var filtered = collection.Where(item => !tos.Contains(item.From));
您可能需要检查,创建哈希集是否真的像这样工作,或者是否需要以不同的方式构造它。。。但你明白了。如果tos变得相当长,那么集合是有效的,因为您将对此进行大量检查…说您的对象集合如下所示:
var list = collection.Select(c=>c.To).Distinct().ToList();
var result = collection.Where(c=>!list.Contains(c.From)).ToList();
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))
假设您的对象集合如下所示:
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))
如果使用“到”和“从”作为各自的键将集合重新连接到自身,则可以确定哪些项通过“到/从”连接并排除它们:
var itemsThatAreConnected =
collection.Join(collection, x => x.To, x => x.From, (a,b) => a);
var unconnected = collection.Except(itemsThatAreConnected);
如果使用“到”和“从”作为各自的键将集合重新连接到自身,则可以确定哪些项通过“到/从”连接并排除它们:
var itemsThatAreConnected =
collection.Join(collection, x => x.To, x => x.From, (a,b) => a);
var unconnected = collection.Except(itemsThatAreConnected);
首先,您的示例与问题文本并不匹配,因为所有示例对象都有一个To对应于其他From。但假设问题文本是正确的,而样本是错误的: 用一个: 或者,首先建立一组不同于的:
var distinctFroms = new HashSet<string>(collection.Select(item => item.From));
var query = from obj in collection
where !distinctFroms.Contains(obj.To)
select obj;
首先,您的示例与问题文本并不匹配,因为所有示例对象都有一个To对应于其他From。但假设问题文本是正确的,而样本是错误的: 用一个: 或者,首先建立一组不同于的:
var distinctFroms = new HashSet<string>(collection.Select(item => item.From));
var query = from obj in collection
where !distinctFroms.Contains(obj.To)
select obj;
实际上是这样的,一个HashSet构造函数接受IEnumerable,因为Linq Select返回IEnumerable,这将编译并工作。我也喜欢MoreLINQ ToHashSet扩展方法,您不需要声明泛型参数,所有都是推断出来的。@IlyaIvanov:很好。我喜欢它,当一个框架按照预期工作时!实际上是这样的,一个HashSet构造函数接受IEnumerable,因为Linq Select返回IEnumerable,这将编译并工作。我也喜欢MoreLINQ ToHashSet扩展方法,您不需要声明泛型参数,所有都是推断出来的。@IlyaIvanov:很好。我喜欢它,当一个框架按照预期工作时!