我有一个List<DiscountRule>
,我需要迭代这些检查以查看是否有任何规则相互冲突。该规则有一些属性,例如BrandID
和CategoryID
,用于指示规则适用的品牌和类别以及Include/Exclude
标记。
如果出现以下示例条件,则如果类别和品牌都与现有规则匹配,则规则会发生冲突:
规则1
包含品牌包含类别
规则2
排除品牌排除类别
如果规则包括排除和排除包含,反之亦然,我也会检查是否会发生冲突。
我需要一种循环遍历这些并标记列表中发生冲突的方法。这是我现在拥有的:
public bool CheckDiscountRuleClash(DiscountRule other)
{
if (this.CategoryId == other.CategoryId && this.BrandId == other.BrandId)
{
if (this.BrandInclude && this.CategoryInclude
&& !other.BrandInclude && !other.CategoryInclude)
{
this.RuleClashes = true;
return true;
}
else if (!this.BrandInclude && !this.CategoryInclude
&& other.BrandInclude && other.CategoryInclude)
{
this.RuleClashes = true;
return true;
}
else if (this.BrandInclude && !this.CategoryInclude
&& !other.BrandInclude && other.CategoryInclude)
{
this.RuleClashes = true;
return true;
}
else if (!this.BrandInclude && this.CategoryInclude
&& other.BrandInclude && !other.CategoryInclude)
{
this.RuleClashes = true;
return true;
}
else
{
this.RuleClashes = false;
return false;
}
}
return false;
}
我称之为:
rules.Where(i1 => rules.Any(i2 => i1.CheckDiscountRuleClash(i2))).ToList();
但这显然只能让我回到那些满足Any()
条件的人。有办法做我想做的事吗?
答案 0 :(得分:0)
要找回符合条件的所有对,只需将每个序列投影到匹配项中:
var conflictingRules = rules.SelectMany(rule =>
rules.Where(other => rule.CheckDiscountRuleClash(other))
.Select(other=> new { rule, other }));
答案 1 :(得分:0)
如何使用foreach循环来确保浏览列表中的每个项目
foreach (var rule in rules) // where rules is your List<DiscountRule>
{
var result = CheckDiscountRuleClash(rule);
// do something with the result here (boolean)
...
}
答案 2 :(得分:-1)
您可以使用Linq join以线性时间执行此操作:
var conflictingRules =
from rule in rules
join other in rules
on new{rule.BrandId, rule.CategoryId, rule.BrandInclude, rule.CategoryInclude} equals new{other.BrandId, other.CategoryId, BrandInclude = !other.BrandInclude, CategoryInclude = !other.CategoryInclude}
select new{rule, other};
我们的想法是将列表与“对应方”一起加入 - 已知的那些与另一方相冲突。 如果需要,同样的方法还允许您将算法与SQL数据库一起使用。
请注意,此算法在线性时间内工作,优于迭代所有对(例如,使用SelectMany,即O(N ^ 2)),其他答案通过数量级,从列表几个品牌的doesens类别。
另请注意,此代码不使用原始的CheckDiscountRuleClash代码,因此它的代码小30行代码 。 您可以在此处查看实时代码并进行性能比较: https://dotnetfiddle.net/ZtRfcz
请注意,如果稍微增加数字,那么慢速方法会在dotnetfiddle上以5秒的时间执行超时。计算复杂性严重!