我正在做一个Web应用程序,我有一个用于搜索对象列表的文本框。
对象就像:
public class Project : IDbProject
{
public string ProjectName { get; set; }
public string Country { get; set; }
public string Customer { get; set; }
public DateTime UploadDate { get; set; }
public DateTime CreateDate { get; set; }
public string CreatedBy { get; set; }
}
,列表是IList<IProject>
。
我的搜索/过滤将通过列表进行比较,并与对象中的每个字符串进行比较,如:
public IList<IProject> GetSearchedProjects(string searchString)
{
foreach (var proj in _projects)
{
if (InputStartWithSearch(proj.ProjectName, searchString) && !searchProjects.Contains(proj))
{
searchProjects.Add(proj);
continue;
}
if (InputStartWithSearch(proj.Country, searchString) && !searchProjects.Contains(proj))
{
searchProjects.Add(proj);
continue;
}
if (InputStartWithSearch(proj.CreatedBy, searchString) && !searchProjects.Contains(proj))
{
searchProjects.Add(proj);
continue;
}
if (InputStartWithSearch(proj.ProjectState, searchString) && !searchProjects.Contains(proj))
{
searchProjects.Add(proj);
continue;
}
if (IsStringDate(searchString))
if (IsDatesEqual(proj.CreateDate, searchString) && !searchProjects.Contains(proj))
{
searchProjects.Add(proj);
}
}
return searchProjects;
}
return _projects;
}
正如您所看到的,我已经制作了许多私有方法,它们将使用对象的字符串/日期/等来检查搜索字符串。 一切正常。
但有没有更好/更快的方法通过单个字符串搜索对象列表?
修改
方法InputStartWithSearch
和IsStringDate
是私有方法,我检查输入字符串是否以项目的数据开头。因此,如果CreatedBy是“Matthi Smith Junior”,并且我搜索了“Matthi Junior”,“Matthi Smith”,“Smith Junior”等,它将添加它。
IsStringDate正在检查搜索字符串是否等于Datetime格式。因此它包含一系列格式,并检查搜索字符串是否采用该格式。
答案 0 :(得分:2)
你想要的是一个重载方法:
bool InputStartWithSearch(string search, params string[] inputs)
{
return inputs.Any(i => InputStartWithSearch(i, string));
}
然后你可以像这样使用它:
if (InputStartWithSearch(searchString, proj.ProjectName, proj.Country, proj.CreateDate))
{
searchProjects.Add(proj);
}
您可以根据需要制作字符串列表。
反转原始方法中参数的顺序可能是一个好主意,也可以减少混淆。
要直接使用LINQ获取匹配项目列表,您可以这样做:
var matchingProjects = _projects.Where(i => InputStartWithSearch(searchString, i.ProjectName, i.Country, i.CreateDate));
答案 1 :(得分:0)
您可以轻松地更改代码并使用Dictionary对象,其中键是项目名称,值是您的对象。你的课程将成为:
public class Project : IDbProject
{
public string Country { get; set; }
public string Customer { get; set; }
public DateTime UploadDate { get; set; }
public DateTime CreateDate { get; set; }
public string CreatedBy { get; set; }
}
然后,您将创建一个新的字典对象
Dictionary <string, Project> myProjects = new Dictionary<string, Project>();
然后你填充它,将字符串设置为项目名称,当你想引用它时,你会执行以下操作:
Project projectDetails = myProjects["projectName"];
显然将“projectName”更改为您需要的那个。
基于你可以做的Starts(代码未经测试)
Project projectDetails = myProjects.Where (m => m.Key.Contains ("projectName").Select (m => m.Value);
答案 2 :(得分:0)
首先,您可以将searchProjects.Contains()检查重构为循环顶部的guard语句。这会简化事情。然后,您可以将每个项目的属性连接成一个具有唯一分隔符的字符串。然后搜索更容易。这并不比现有方法快,只是更短。
public IList<IProject> GetSearchedProjects(string searchString)
{
foreach (var proj in _projects)
{
if (!searchProjects.Contains(proj))
continue;
StringBuilder sb = new StringBuilder();
sb.Append("|").Append(proj.ProjectName);
sb.Append("|").Append(proj.Country);
sb.Append("|").Append(proj.CreatedBy);
sb.Append("|").Append(proj.UploadDate.ToString());
if (sb.ToString().Contains("|" + searchString))
searchProjects.Add(proj);
}
return searchProjects;
}
只要'|'字符不会出现在任何字段中......
答案 3 :(得分:0)
你可以使用linq。同样,它并不快,但代码更简单。
public IList<IProject> GetSearchedProjects(string searchString)
{
return (from p in _projects
where searchProjects.Contains(p) &&
(InputStartWithSearch(p.ProjectName, searchString) ||
InputStartWithSearch(p.Country, searchString) ||
InputStartWithSearch(p.CreatedBy, searchString) ||
DateToString(p.CreateDate).Contains(searchString.ToLower()))
select p).ToList();
}