2010-11-10 26 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);