单个字符串最快的对象搜索列表

时间:2013-10-24 08:54:39

标签: c# list search

我正在做一个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;
    }

正如您所看到的,我已经制作了许多私有方法,它们将使用对象的字符串/日期/等来检查搜索字符串。 一切正常。

但有没有更好/更快的方法通过单个字符串搜索对象列表?

修改

方法InputStartWithSearchIsStringDate是私有方法,我检查输入字符串是否以项目的数据开头。因此,如果CreatedBy是“Matthi Smith Junior”,并且我搜索了“Matthi Junior”,“Matthi Smith”,“Smith Junior”等,它将添加它。

IsStringDate正在检查搜索字符串是否等于Datetime格式。因此它包含一系列格式,并检查搜索字符串是否采用该格式。

4 个答案:

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