我正在研究一个简单的搜索功能。用户输入关键字request.Keyword
并期望搜索功能“找出”他想要的,然后使用关键字在该集合中进行搜索。 的三个选项是Name
,Number
或Code
我首先提出的是以下
// 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();
}
}
}
}
正如您所看到的,嵌套非常糟糕(这是简化的代码)。添加新的收藏会使情况变得更糟......
如何通过(或多或少)干净的代码实现这一目标?
答案 0 :(得分: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 :(得分:1)
如果您提取此方法以便返回结果而不是继续,则可以跳过所有else
。
// 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;
答案 2 :(得分:1)
如果您的请求符合Name
或Number
或Code
中的任何一项,并且如果您需要所有这些请求,您的代码可以简化如下。
var searchResults = _items.Where(x => x.Name.Contains(request.Keyword) ||
x.Number == request.Keyword ||
x.Code == request.Keyword)
.ToList();
if(!searchResults.Any())
{
_items.Clear();
}