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

本文关键字:列表 对象 单个 字符串 搜索 | 更新日期: 2023-09-27 18:36:37

我正在做一个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 正在检查搜索字符串是否等于日期时间格式。因此,它包含一系列格式,并检查搜索字符串是否为该格式。

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

你想要

的是一个重载的方法:

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));

您可以稍微更改代码并使用 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"];

显然,将"项目名称"更改为您需要的名称。

编辑

基于您可以做的开始(代码未经测试)

Project projectDetails = myProjects.Where (m => m.Key.Contains ("projectName").Select (m => m.Value);
首先,

你可以重构 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;
}

只要"|"字符不出现在任何字段中...

你可以使用 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();
}