2014-07-25 1 views
0

Je travaille sur une fonction de recherche simple. L'utilisateur entre un mot-clé request.Keyword et s'attend à ce que la fonction de recherche "découvre" recherche, puis recherche dans cette collection avec le mot-clé. Les trois options pour le ce sont Name, Number ou CodeFonction de recherche qui arrête de chercher plus loin après avoir trouvé un résultat

Ce que je suis arrivé avec est le suivant

// 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; 
} 

Le problème ici est que le produit du programme dans le if -bloc après avoir trouvé un résultat de la recherche et continue à chercher dans les autres collections. Mais puisque nous avons déjà un résultat de recherche, ce serait inutile.

Le deuxième problème est que _items reste inchangé quand aucun résultat de recherche n'a été trouvé. Mais en fait, l'utilisateur s'attend à ce qu'il soit vide dans ce cas.

Dans le code, ce que je veux réaliser, ressembleraient cette beauté:

// 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(); 
      } 
     } 
    } 
} 

Comme vous pouvez le voir, l'imbrication est horrible (et ce code est simplifié). L'ajout de nouvelles collections va encore aggraver ...

Comment puis-je y parvenir avec du code (plus ou moins) propre?

+1

Si la requête correspond 'Name' et' Number' vous voulez retourner les deux ou ..? –

Répondre

1

Si vous extrayez cette méthode de sorte que vous renvoie le résultat au lieu de continuer, vous pouvez sauter toutes les 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

Parfait merci. – Sandro

2

Way 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; 
} 

Way 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

Si votre demande correspond à l'une des Name ou Number ou Code, et si vous avez besoin tous votre code peut être simplifiée comme suit.

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

C'est une belle façon. Mon code posté était un peu simplifié. Il y a d'autres choses qui se passent aussi. Mais je pourrais les extraire et les utiliser directement dans la requête. – Sandro

Questions connexes