2014-07-25 64 views
0

我正在一個簡單的搜索功能。用戶輸入關鍵字request.Keyword,並期望搜索功能「找出」他在尋找什麼,然後使用關鍵字在該集合中進行搜索。三個選項爲什麼NameNumberCode搜索功能,找到一個結果後,停止進一步尋找

我第一次來到了在以下

// Keyword filter 
if (!string.IsNullOrWhiteSpace(request.Keyword)) 
{ 
    var searchResults = _items.Where(x => x.Name.Contains(request.Keyword)).ToList(); 
    if (searchResults.Any()) _items = searchResults; 

    searchResults= _items.Where(x => x.Number == request.Keyword).ToList(); 
    if (searchResults.Any()) _items = searchResults; 

    searchResults= _items.Where(x => x.Code == request.Keyword).ToList(); 
    if (searchResults.Any()) _items = searchResults; 
} 

這裏的問題是,該程序進入在if - 塊找到後搜索結果並繼續在其他集合中進行搜索。但既然我們已經有了搜索結果,那就沒有必要了。

第二個問題是,當沒有找到搜索結果時,_items保持不變。但事實上,在這種情況下,用戶期望它是空的。

在代碼中,我想達到的目標,應該是這樣的美:

// Keyword filter 
if (!string.IsNullOrWhiteSpace(request.Keyword)) 
{ 
    var searchResults = _items.Where(x => x.Name.Contains(request.Keyword)).ToList(); 
    if (searchResults.Any()) 
    { 
     _items = searchResults; 
    } 
    else 
    { 
     searchResults = _items.Where(x => x.Number == request.Keyword).ToList(); 
     if (searchResults.Any()) 
     { 
      _items = searchResults; 
     } 
     else 
     { 
      searchResults = _items.Where(x => x.Code == request.Keyword).ToList(); 
      if (searchResults.Any()) 
      { 
       _items = searchResults; 
      } 
      else 
      { 
       // Keyword was set, but no result was found. 
       _items.Clear(); 
      } 
     } 
    } 
} 

正如你所看到的,嵌套是可怕的(這是簡化的代碼)。添加新的收藏將使它更糟......

我怎樣才能實現這個(或多或少)乾淨的代碼?

+1

如果請求匹配'Name'和'Number',你想返回兩個或..? –

回答

1

如果您提取此方法,以便您返回的結果,而不是繼續,你可以跳過所有else s。

// Keyword filter 
if (string.IsNullOrWhiteSpace(request.Keyword)) 
{ 
    return emptyList; 
} 
var searchResults = _items.Where(x => x.Name.Contains(request.Keyword)).ToList(); 
if (searchResults.Any()) 
{ 
    return searchResults; 
} 
searchResults = _items.Where(x => x.Number == request.Keyword).ToList(); 
if (searchResults.Any()) 
{ 
    return searchResults; 
} 
searchResults = _items.Where(x => x.Code == request.Keyword).ToList(); 
if (searchResults.Any()) 
{ 
    return searchResults; 
} 

return emptyList; 
+0

非常感謝。 – Sandro

2

路1

// Keyword filter 
var keyword = request.Keyword; 
if (!string.IsNullOrWhiteSpace(keyword)) 
{  
    var searchResults = _items.Where(x => x.Name.Contains(keyword)).ToList(); 
    if (searchResults.Length == 0) 
     searchResults = _items.Where(x => x.Number == keyword).ToList(); 
    if (searchResults.Length == 0) 
     searchResults = _items.Where(x => x.Code == keyword).ToList();  
    if (searchResults.Length == 0) 
     _items.Clear(); 
    else 
     _items = searchResults; 
} 

路2

public static List<Item> Search(List<Item> items, Predicate<Item> predicate) 
{ 
    var searchResults = items.Where(predicate).ToList(); 
    return searchResults.Any() ? searchResults : null; 
} 

// Keyword filter 
var keyword = request.Keyword; 
if (!string.IsNullOrWhiteSpace(keyword)) 
{  
    _items = 
     Search(_items, x => x.Name.Contains(keyword)) ?? 
     Search(_items, x => x.Number == keyword) ?? 
     Search(_items, x => x.Code == keyword) ?? 
     new List<Item>(); 
} 
1

如果您的請求在任何NameNumberCode匹配,如果你需要所有這些代碼可以如下簡化。

var searchResults = _items.Where(x => x.Name.Contains(request.Keyword) || 
             x.Number == request.Keyword  || 
             x.Code == request.Keyword) 
          .ToList(); 

if(!searchResults.Any()) 
{ 
    _items.Clear(); 
} 
+0

這是一個不錯的方法。我發佈的代碼有點簡化。還有一些其他的東西也在發生。但是我可以直接在查詢中提取和使用它們。 – Sandro