2010-11-10 27 views
1

我有一个逻辑问题。我收集了员工对象 有3个过滤条件条件,它们具有句柄 员工姓名,办公室名称,工资。处理(2升至n)-1条件

现在这些过滤器标准应与像(员工姓名和/或Office名称和/或工资)

所以在这里我不得不写(2升N)-1,如果条件来处理这种情况。

有没有其他办法可以做到这一点。 对于(员工姓名和/或Office的名字)的病情,我在做以下

if (criteria.EmpName != "" && criteria.OfficeName != "") 
    { 
     if (emp.EmpName == criteria.EmpName && emp.OfficeName == criteria.OfficeName) 
     { 
       bIsMatch = true; 
     } 
    } 
    else 
    { 
      if (criteria.EmpName != "" && emp.EmpName == criteria.EmpName) 
      bIsMatch = true; 
      else if (criteria.OfficeName != "" && emp.OfficeName == criteria.OfficeName) 
      bIsMatch = true; 
    } 

现在如果有saraly处理我也有写分5个条件。

其他方式做到这一点?

+5

“2升N” 可以写为2^N – 2010-11-10 05:30:16

+1

我严重怀疑你在C#,Java的,和C++编程在同一时间。你为什么说谎? – GManNickG 2010-11-10 05:39:02

+0

我正在c#上工作。但是这个问题比特定的语言更合乎逻辑。 – 2010-11-10 05:47:40

回答

1

您可以配对的过滤条件,并具有编码的所有参数的单个语句:

if((criteria.EmpName.equals("") || criteria.EmpName.equals(emp.EmpName)) 
    && (criteria.OfficeName.equals("") || criteria.OfficeName.equals(emp.OfficeName)) 
    && (criteria.Salary.equals("") || criteria.Salary.equals(emp.Salary))) 

在每个AND-ED的表现首先检查,如果过滤器是空的,如果它是那片将导致true,如果不是,则检查是针对emp中的相应值执行的,并且仅在该检查为true时为true

+0

我讨厌维护这样的代码。但它工作,所以没有-1 – 2010-11-10 06:19:12

+0

谢谢马克。我认为这是最好的和完美的解决方案。这样,我不需要添加多个条件。这并不容易理解,但你解释得很好。 – 2010-11-10 07:24:28

1

从假设你有一个匹配开始,然后逐个应用每个标准。

bIsMatch = true; 

if (bIsMatch && criteria.EmpName != "") bIsMatch = emp.EmpName == criteria.EmpName; 
if (bIsMatch && criteria.OfficeName != "") bIsMatch = emp.OfficeName == criteria.OfficeName; 
// ... 

或者,写一个帮助函数来完成匹配。

bool IsMatch(String criterion, String value) 
{ 
    return criterion == "" || criterion == value; 
} 

然后,您可以做的一切一个大的if语句:

if (IsMatch(criteria.EmpName, emp.EmpName) && 
    IsMatch(criteria.OfficeName, emp.OfficeName) && 
    ... 
    ) 
2

有很多方法可以做到这一点,但因为你没有指定一个特定的语言,因为我不觉得有资格去判断您的编码风格,这里有一个,让您的代码的一般形式,同时展示一些更好的逻辑:

bool bIsMatch = true; 
if (criteria.EmpName != "" && criteria.EmpName != emp.EmpName) { 
    bIsMatch = false; 
} else if (criteria.OfficeName != "" && criteria.OffIceName != emp.OfficeName) { 
    bIsMatch = false; 
} /* Repeat for as many conditions as there are */ 

if (bIsMatch) { 
    /* None of the checks above failed */ 
} 
+0

我认为这是最好的方法,因为它是最容易理解和维护的。 – 2010-11-10 06:11:53

+0

如果没有检查任何条件,如果您不需要返回false,您也可以在发现错误*时立即短路并立即返回。 – 2010-11-10 06:17:35

+0

如果我仅搜索办公室名称,这不起作用。 – 2010-11-10 07:24:52

1

可以单独检查的标准和保持比赛的计数。这样你只需要n条件:

​​
+0

与霍布斯的答案类似,但你真正追求的是有任何不匹配,而不是多少。 – 2010-11-10 06:18:30

1

这个怎么样?这个想法可以很好地适应更多的过滤器,除了映射本身是约定(基于名称)。

var map = new Dictionary<string, string> 
       { 
       { criteria.EmpName, emp.EmpName },  
       { criteria.OfficeName, emp.OfficeName}, 
       { criteria.ThirdProp, emp.ThirdProp } 
       }; 

bIsMatch = dict.All(kvp => string.IsNullOrEmpty(kvp.Key) || kvp.Key == kvp.Value); 

虽然我会质疑总体设计;有些东西似乎并不正确。你如何处理你提到的Salary字段?当然,那不是string?这种情况下使用的哨兵值是多少?

+0

工资将是整数。用户可以搜索以Emp1开始的员工姓名,办公室名称ABC,工资> 10000 – 2010-11-10 05:53:28

0

单独测试每个问题并使用一组位来编码答案的组合。

这将导致更干净的代码,因为你只测试标准,每一次,它的紧凑而可读的,但你可以在代码来处理每个组合容易堵塞。而且速度也很快。 O(n)来测试所有的标准和O(1)来找到实际的组合。

对于一小部分固定数量的标准,您可以手动推动位。对于许多标准,或者对于扩展的溶液中,使用java.util.BitSet中

位推例如:

int bits = 0; 

if (...criteria 1...) { 
    bits = 1; 
} 

if (...criteria 2...) { 
    bits |= 2; 
} 

if (...bits 3...) { 
    bits |= 4; 
} 

switch (bits) { 
case 0: // no criteria matched 
    ; 
case 1: // criteria 1 matched 
    ; 
case 2: // criteria 2 matched 
    ; 
case 3: // criteria 1 AND 2 matched 
    ; 
case 4: // criteria 3 matched 
    ; 
case 5: // criteria 1 AND 3 matched 
    ; 
case 6: // criteria 2 AND 3 matched 
    ; 
case 7: // criteria 1 AND 2 AND 3 matched 
    ; 
} 

可以使用java.util.BitSet中操纵对于n比特的标准一般化该溶液(当n> 64时很有用!)。为了便于快速查找,请将每个BitSet组合的散列存储在将散列代码映射到命令类的映射中。

1

在编写代码之前,请确保您已清楚了解业务逻辑。根据你的代码,我可以看到,要检查是否empcriteria具有相同的EmployeeNameOfficeName,任何属性被认为是相同的,如果它是string.Empty。自己清楚后,代码将非常清晰。在这里,我们去:

public static bool EmptyOrEquals(this string one, string another) 
{ 
    return string.IsNullOrEmpty(another) || one.Equals(another); 
} 
bIsMatch = emp.EmpName.EmptyOrEquals(criteria.EmpName) 
      && emp.OfficeName.EmptyOrEquals(criteria.OfficeName);