2013-10-24 5 views
-1

개체 목록을 검색하기위한 텍스트 상자가있는 웹 응용 프로그램을 만들고 있습니다.단일 문자열로 가장 빠른 개체 목록 검색

개체는 같다 :

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 형식과 같은지 확인합니다. 따라서 일련의 형식이 포함되어 있으며 검색 문자열이 해당 형식인지 확인하십시오.

+3

- 지금이 당신이 실제로 있나요 성능 문제? * 간단한 * 코드를 먼저 집중하겠습니다. –

+1

또한 InputStartWithSearch 및 DateToString은 무엇을합니까? 그리고'searchProjects'는 어디에서 왔습니까? foreach 루프 내에 return 문이있는 이유는 무엇입니까? 그것은 나에게 매우 잘못 보인다. 명확하고 정확한 코드를 먼저 얻는 데 중점을 둡니다. –

+0

현재 약 30 개의 더미 개체 만 사용하고 있지만 데이터베이스에 연결될 때는 1000 개 이상의 개체가됩니다. 그래서 일하고 있지만, 누군가가 그것을 더 빨리 만들 수있는 방법을 볼 수 있다면, 그것이 지금 일어나고있을 때보 다 지금 그것을 바꾸는 것이 낫습니다. – Moelbeck

답변

2

은 당신이 원하는 것은 오버로드 방법 처럼.

원래의 방법으로 매개 변수의 순서를 뒤집어 혼란을 줄이는 것이 좋습니다.

일치하는 프로젝트의 목록을 직접 LINQ를 사용하려면, 당신은 할 수 :

당신은 "더 빨리"에 대해 이야기
var matchingProjects = _projects.Where(i => InputStartWithSearch(searchString, i.ProjectName, i.Country, i.CreateDate)); 
+2

이렇게하면 더 빨라지습니까? 아니면 "더 예쁘고 간단하게"단순하게 보이나요? 나는 당신의 솔루션이 실제로 마음에 들지 않았다. – Moelbeck

+0

근본적으로 더 빨라지지는 않을 것입니다. 여전히 일치하는 것을 찾기 위해 시리얼 검색을하고 있습니다. 그러나 가독성과 코드 명확성은 그 자체로 진정한 가치를 제공합니다. Jon Skeet이 주석에서 암시 한 바와 같이, 이것은 아마도 코드에서 병목 현상이되지 않을 것입니다. 따라서 명확성을 유지하는 것이 여기에서 최적화보다 중요 할 수 있습니다. – Baldrick

0

코드를 슬 라이트하게 변경하고 사전 개체를 사용할 수 있습니다. 여기서 키는 프로젝트 이름이고 값은 개체입니다. 귀하의 클래스는 될 것입니다 :

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"을 필요한 것으로 변경하십시오. 당신은 당신이합니다 (searchProjects.Contains를 리팩토링 수있는 모든의

Project projectDetails = myProjects.Where (m => m.Key.Contains ("projectName").Select (m => m.Value); 
+0

검색 결과가 사전으로 작동하지 않는 것처럼 보입니다. –

0

우선 (테스트되지 않은 코드))의 상단에 가드 문에 체크인을 할 수와 함께 시작을 바탕으로

편집

고리. 그것은 사물을 단순화합니다. 그런 다음 각 프로젝트의 속성을 고유 한 구분 문자가있는 단일 문자열로 연결할 수 있습니다. 그러면 검색이 더 쉬워집니다. 기존 방법보다 빠르지 않습니다. 단지 짧습니다.

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

'|' 문자가 필드에 나타나지 않습니다 ...

0

linq를 사용할 수 있습니다. 다시 말하지만 코드가 더 간단합니다.당신만큼 당신은 문자열의 목록을 만들 수 있습니다

if (InputStartWithSearch(searchString, proj.ProjectName, proj.Country, proj.CreateDate)) 
{ 
    searchProjects.Add(proj); 
} 

가 확인 :

bool InputStartWithSearch(string search, params string[] inputs) 
{ 
    return inputs.Any(i => InputStartWithSearch(i, string)); 
} 

그런 다음이처럼 사용할 수 있습니다

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

표준 문자열을 사용하고 있지 않습니다 .StartWith(). 나는 문자열을 분리하고 부분 문자열이 그 문자열로 시작하는지 확인해야했습니다. ProjectName이 "Project number 10"이고 "Project 10", "Number 10"또는 "Project"를 검색 한 경우 해당 이름이 목록에 추가됩니다. 그래서 나는 내 자신의 확인을했다. – Moelbeck

+0

ok InputStartWithSearch를 사용하도록 변경했습니다. –

관련 문제