LINQ在内部集合上相交

时间:2016-03-04 00:07:16

标签: c# linq

我有一个商店列表(类型为//Point.hpp class Point { friend class Proxy; private: double *val; int i; int amount; public: Point(); Point(const int&); void Set(const int &); double Get(const int &); int Amount(); Proxy operator += (const double &add); }; class Proxy { private: int &i; Point &temp_point; public: Proxy operator , (const double&); Proxy(Point2D &, int&); }; //Point.cpp Point::Point() { this->amount = 2; val = new double[this->amount]; val[0] = 0; val[1] = 0; }; Point::Point(const int &amount) : amount(amount) { val = new double[amount]; for (int i = 0; i < amount; i++) { val[i] = 0; } }; void Point::Set(const int &nr) { do { std::cout << "Give me value of " << nr << " coordinate: "; std::cin.clear(); std::cin.sync(); std::cin >> val[nr]; if (std::cin.fail()) { std::cout << "Try again, not acceptable...\n"; } } while (std::cin.fail()); } double Point::Get(const int &nr) { return val[nr]; } int Point::Amount() { return this->amount; } Proxy Point::operator += (const double &add) { this->i = 0; this->val[i++] += add; return Proxy(*this, i); } Proxy::Proxy(Point &point, int &i) : temp_point(point), i(i) {} Proxy Proxy::operator , (const double &value) { temp_point.val[i++] += value; return Proxy(temp_point, i); } //Source.cpp example int main() { Point example(3); example += 4.5, -2.3, 3.0; for (int i = 0; i < example.Amount(); i++) { std::cout << example.Get(i) << " "; } std::cout << std::endl; system("PAUSE"); return 0; } ),ObservableCollection<Store>对象有一个名为功能的属性(类型为{{ 1}})。并且Store对象具有名称属性(类型为List<Feature>)。

回顾一下具有功能列表

的商店列表

我有第二个 DesiredFeatures (类型为Feature)的集合。

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

这就是看起来的样子:

string

我知道List<string>可以提供帮助,以下是我如何使用它:

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

这就是我被困的地方,Intersect想要一个Intersect对象,我需要交叉的是在Feature.Name上。

目标是最终得到一个ObservableCollection,其中每个商店都拥有所有DesiredFeatures。

谢谢!

4 个答案:

答案 0 :(得分:2)

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

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

这意味着只需要在商店功能中包含所需功能的商店。

答案 1 :(得分:1)

继续你的想法,我想到的唯一方法是使用Select将Store.Features(List<Feature>)作为功能名称列表({{1} })并与DesiredFeatures相交。

更新答案:

List<string>

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

旧答案(如果DesiredFeatures为var q = Stores.Where(s => DesiredFeatures.Intersect(s.Features.Select(f => f.Name)).Any());

List<Feature>

答案 2 :(得分: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()
);

答案 3 :(得分: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中的唯一性,如果不正确则修改注释行中所述的代码