使用带有WHERE的LINQ来请求多个可能的结果,而没有冗余"||"命令
本文关键字:quot 命令 结果 冗余 LINQ WHERE 请求 | 更新日期: 2023-09-27 18:09:02
这是一个化妆问题,它只是语法糖,只是因为我想这样做。但基本上我有很多这样的代码…我使用dynamic
纯粹是为了节省时间和举例。
var terms = new List<string> {"alpha", "beta", "gamma", "delta", "epsilon", "rho"};
var list = new List<dynamic> {
new {
Foo = new List<string> {
"alpha",
"gamma"
}
}
};
var result = list
.Where(
n => n.Foo.Contains(terms[0]) ||
n.Foo.Contains(terms[1]) ||
n.Foo.Contains(terms[2]) ||
n.Foo.Contains(terms[3]) ||
n.Foo.Contains(terms[4]) ||
n.Foo.Contains(terms[5]))
.ToList();
显然这是一个可笑的夸张的例子,更准确的代码是…
Baseline =
Math.Round(Mutations.Where(n => n.Format.Is("Numeric"))
.Where(n => n.Sources.Contains("baseline") || n.Sources.Contains("items"))
.Sum(n => n.Measurement), 3);
但基本的一点是,我有很多地方,我想检查,看看如果一个List<T>
(通常是List<string>
,但有时可能有其他对象。string
是我目前的重点)包含来自另一个List<T>
的任何项目。
我认为使用.Any()
会起作用,但我实际上还没有能够像预期的那样发挥作用。到目前为止,只有过量的"||"
才能产生正确的结果。
这在功能上很好,但是写起来很烦人。我想知道是否有一种更简单的方法来写这个——一个扩展方法,或者一个LINQ
方法,也许我还没有理解。
我真的知道这个可能是重复的,但是我很难把问题的措辞精确到我可以找到重复的程度。如有任何帮助,不胜感激。
<标题> 解决方案非常感谢你所有的帮助。这是完整的解。我在这里使用dynamic
只是为了节省示例类的时间,但是您提出的几个解决方案都有效。
var terms = new List<string> {"alpha", "beta", "gamma", "delta", "epsilon", "rho"};
var list = new List<dynamic> {
new { // should match
Foo = new List<string> {
"alpha",
"gamma"
},
Index = 0
},
new { // should match
Foo = new List<string> {
"zeta",
"beta"
},
Index = 1
},
new { // should not match
Foo = new List<string> {
"omega",
"psi"
},
Index = 2
},
new { // should match
Foo = new List<string> {
"kappa",
"epsilon"
},
Index = 3
},
new { // should not match
Foo = new List<string> {
"sigma"
},
Index = 4
}
};
var results = list.Where(n => terms.Any(t => n.Foo.Contains(t))).ToList();
// expected output - [0][1][3]
results.ForEach(result => {
Console.WriteLine(result.Index);
});
标题>标题>
我认为使用
.Any()
会起作用,但我实际上还没有能够像预期的那样发挥作用。
您应该能够通过将Any()
应用于terms
来使其工作,如下所示:
var result = list
.Where(n => terms.Any(t => n.Foo.Contains(t)))
.ToList();
你可以试试这个:
var result = list.Where(terms.Contains(n.Foo))
.ToList();
我假设n.Foo是一个字符串而不是一个集合,在这种情况下:
var terms = new List<string> { "alpha", "beta", "gamma", "delta", "epsilon", "rho" };
var list = (new List<string> { "alphabet", "rhododendron" })
.Select(x => new { Foo = x });
var result = list.Where(x => terms.Any(y => x.Foo.Contains(y)));
您想知道一个集合中的Any
元素是否存在于另一个集合中,因此Intersect
在这里应该可以很好地工作。
你可以相应地修改你的第二个代码片段:
var sources = new List<string> { "baseline", "items" };
Baseline =
Math.Round(Mutations.Where(n => n.Format.Is("Numeric"))
.Where(n => sources.Intersect(n.Sources).Any())
.Sum(n => n.Measurement), 3);
关于你为"机密数据库"引用的部分文档:
使用默认的相等比较器比较值,产生两个序列的集合交集。
每个对象都可以与相同类型的对象进行比较,以确定它们是否相等。如果它是你创建的自定义类,你可以实现IEqualityComparer
,然后你可以决定什么使你的类的两个实例"相等"。
然后调用"Any()"来确定第三个集合中是否有元素,这告诉我们两个原始集合之间至少有一个匹配
如果使用Any()
时性能是一个问题,您可以使用正则表达式代替。显然,您应该度量以确保正则表达式执行得更快:
var terms = new List<string> { "alpha", "beta", "gamma", "delta", "epsilon", "rho" };
var regex = new Regex(string.Join("|", terms));
var result = list
.Where(n => regex.Match(n.Foo).Success);
这假设将术语连接到一个列表中创建一个有效的正则表达式,但是使用简单的单词应该没有问题。
使用正则表达式的一个优点是,您可以要求术语被单词边界包围。此外,与在Any
中使用Contains
的解决方案相比,Where
子句中的谓词可能更容易理解。