我有两种不同的列表类型。我需要从list1中删除list2中不存在的元素,list2元素满足某些条件。
这是我尝试过的,似乎有效,但每个元素都列出了两次。
var filteredTracks =
from mtrack in mTracks
join ftrack in tracksFileStatus on mtrack.id equals ftrack.Id
where mtrack.id == ftrack.Id && ftrack.status == "ONDISK" && ftrack.content_type_id == 234
select mtrack;
理想情况下,我不想创建filteredTracks的新副本,是否可以修改mTracks?
答案 0 :(得分:4)
如果您正在获得重复项,那是因为您的id
字段在两个序列中的一个或两个中都不是唯一的。此外,您不需要说where mtrack.id == ftrack.Id
,因为必须满足该条件才能使联接成功。
我可能会在这里使用循环,但是如果您在LINQ上设置了死区,则可能需要将tracksFileStatus
字段分组为Id
。你发布的内容很难说清楚。
就“修改mTracks
到位”而言,这可能是不可能或不值得的(我假设mTracks
是从IEnumerable<T>
派生的某种类型)。如果您担心这种方法的效率,那么您可能需要考虑使用其他类型的数据结构,例如以Id
值作为键的字典。
答案 1 :(得分:2)
因为Q主要是关于列表...
这可能是更好的明智......
var test = (from m in mTracks
from f in fTracks
where m.Id == f.Id && ...
select m);
但是你应该优化,例如
你的清单是否排序?如果是,请参阅例如Best algorithm for synchronizing two IList in C# 2.0
如果它来自Db(这里不清楚),那么你需要根据你在Db中的SQL /关系和索引构建你的linq查询,然后走一条不同的路线。
如果我是你,我会进行一个查询(对于每个列表,假设它不是Db绑定的),这样轨道首先被排序(并且通常用于比较它们的任何内容),
然后并行枚举(使用枚举器),比较过程中的其他内容(如在该链接中)
这可能是最有效的方式。
if / when它来自数据库,在'source'处进行优化 - 即获取已经排序和过滤的数据尽可能多。基本上,首先构建一个SQL,或者从linq查询中检查返回的SQL(如果需要链接,请告诉我)。