简体   繁体   English

检查列表中的有效项目组合

[英]Checking valid combination of items in list

I have a list of items that I need to validate. 我有一个需要验证的项目列表。 The list can contain any number of items of the type A, B and C, but before the list can be saved, it must confirm to the following rules: 该列表可以包含任意数量的A,B和C类型的项目,但在保存列表之前,它必须符合以下规则:

  1. If you have A, you need either B or C 如果你有A,你需要B或C.
  2. If you have B, you need A 如果你有B,你需要A

I have ended up with the following code (saudo code): 我最终得到了以下代码(saudo代码):

bool IsListValid()
{
  var a = list.ContainsAny(A);
  var b = list.ContainsAny(B);
  var c = list.ContainsAny(C);

  if (!a && !b)
    return true;

  if (a && (b || c)
    return true;

  return false;
}

I don't like this code. 我不喜欢这段代码。
1. The use of Any three times in a row will potentially iterate the list three times 1.连续三次使用Any可能会三次迭代列表
2. The if's doesn't look good to me. 这个if对我来说不好看。

Of cause it would be better with different variable names and by extracting the test into methods with good names, but I think there are better ways of solving this entirely. 因为使用不同的变量名称并将测试提取到具有良好名称的方法会更好,但我认为有更好的方法可以完全解决这个问题。 I'm just not sure how... 我只是不确定...

Any tips? 有小费吗?

I would use a simple loop, it's both, comprehensible and efficient. 我会使用一个简单的循环,它既可理解又高效。

bool containsA = false, containsB = false, containsC = false;
for (int i = 0; i < list.Count; i++)
{
    Type itemType = list[i].GetType();
    if (!containsA) containsA = itemType == typeof(A);
    if (!containsB) containsB = itemType == typeof(B);
    if (!containsC) containsC = itemType == typeof(C);
    if (containsA && (containsB || containsC)) return true;
}
return (!containsA && !containsB);

If it's so important that you only go through the list once, you could do this: 如果您只浏览一次列表非常重要,那么您可以这样做:

bool a = false;
bool b = false;
bool c = false;
foreach(var x in list)
{
  if (x is A) a = true;
  if (x is B) b = true;
  if (x is C) c = true;
}

But I'd leave it as it is. 但我会保持原样。 If profiling later shows that this code is becoming a bottleneck, you can revisit it then. 如果以后的分析显示此代码正在成为瓶颈,那么您可以重新访问它。

As for the if's , that looks fine to me. 至于if's ,那对我来说很好看。 As long as A, B and C are properly named (something like hasNotifyEmail or needsResponse , something that explains why you want them to work with the specified rules) then it should be easy for others to understand. 只要A,B和C被正确命名(类似于hasNotifyEmailneedsResponse ,这就解释了为什么你希望它们使用指定的规则),那么其他人应该很容易理解。

var hasA = list.Any(x => x.GetType() == typeof(A));
var hasB = list.Any(x => x.GetType() == typeof(B));
var hasC = list.Any(x => x.GetType() == typeof(C));

//If you have A, you need either B or C
// A AND (B xor C)
if (hasA && (hasB ^= hasC))
   return true;

//If you have B, you need A
if (hasB && hasA)
   return true;

   return false;

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM