2016-03-04 162 views
2

我有商店(的ObservableCollection<Store>类型)的列表和Store对象有一个名为特点List<Feature>型)属性。和Feature对象有一个名称属性(类型string)。LINQ相交于内收集

总括来说,专卖店的名单有特色

我有DesiredFeatures(的List<string>类型)第二集合的列表。

我需要使用LINQ给我结果所有的DesiredFeatures商店。到目前为止,我只能提出一个查询,该查询给出了结果,而不是

这里是一个样子:

var q = Stores.Where(s=> s.Features.Any(f=> DesiredFeatures.Contains(f.name)));

我知道Intersect能有所帮助,这里是我是如何使用它:

var q = Stores.Where(s => s.Features.Intersect<Feature>(DesiredFeatures));

这是我被困,Intersect想要一个Feature对象,我需要相交的是Feature.Name。

目标是结束一个ObservableCollection,其中每个商店都具有所有DesiredFeatures。

谢谢!

回答

1

我需要使用LINQ给我的唯一结果有全部 DesiredFeatures的商店。

换句话说,每个所需的功能必须具有匹配的存储功能。

我不明白Intersect在这种情况下可以提供什么帮助。上述标准中的LINQ直接翻译是这样的:

var q = Stores.Where(s => 
    DesiredFeatures.All(df => s.Features.Any(f => f.Name == df)) 
); 

更有效的方法可能是使用GroupJoin进行比赛:

var q = Stores.Where(s => 
    DesiredFeatures.GroupJoin(s.Features, 
     df => df, sf => sf.Name, (df, sf) => sf.Any() 
    ).All(match => match) 
); 

Except检查无与伦比的项目:

var q = Stores.Where(s => 
    !DesiredFeatures.Except(s.Features.Select(sf => sf.Name)).Any() 
); 
+0

感谢Ivan,GroupJoin是完美的解决方案,并做到了这一点。 –

2

你几乎已经完成了你所需要的。一个小的改进将是交换DesiredFeaturess.Features

var q = Stores.Where(s => DesiredFeatures.All(df => s.Features.Contains(df))); 

这意味着只采取那些商店的功能都包含所需功能的商店。

+0

非常接近,但我的'df'是一个字符串,而不是一个功能。我想我可以重构DesiredFeatures列表,但这看起来像一个创可贴 –

1

去上你的想法相交,我想使这项工作的唯一方法是通过使用Select得到Store.Features(List<Feature>)为特征的名称(List<string>)的列表,并相交,与DesiredFeatures。

更新答:

var q = Stores.Where(s => s.Features.Select(f => f.Name).Intersect(DesiredFeatures).Any()); 

var q = Stores.Where(s => DesiredFeatures.Intersect(s.Features.Select(f => f.Name)).Any()); 

老回答(如果DesiredFeatures是List<Feature>

var q = Stores.Where(s => s.Features.Select(f => f.Name).Intersect(DesiredFeatures.Select(df => df.Name)).Any()); 
+0

非常接近,但DesiredFeatures是一个'列表'。如果我更改了'DesiredFeatures.Select(df => df)',我会得到与原始尝试相同的结果。 –

+0

哦,道歉。我没有看到DesiredFeatures是一个字符串列表。是功能名称列表还是其他信息?你也应该在你的问题中指定这个。 – Kody

+0

是的,我知道它在我的第一个查询中出现,但谓词中的f.name来自Features。我试图重构列表,而不是因为它可能不那么复杂 –

0

您希望代码执行的两件事。

var q = Stores.Where(s=> s.Features.All(f=> DesiredFeatures.Contains(f.name)) && 
         s.Features.Count() == DesiredFeatures.Count()); // Incude Distinct in the comparison if Features list is not unique 
  • 确保特点是DesiredFeature
  • 商店包含所有期望的功能。

守则Features收集上述假定的独特性以及DesiredFeatures,修改代码作为注释行指出,如果这是不正确的