2014-09-10 104 views
-4

如何以列表匹配字符串的方式對列表進行排序。 想,如果我有在C#中排序列表#

"vishal pandey" 

字符串,然後列表匹配的項目「維沙爾潘迪」是第一位的,那麼它應該表現出含有「維沙爾」和項目包含「潘迪」

這不是項目的結果可能我帶來的順序數據從數據庫 目前我正在列表這樣

var matchedProjects = (from project in unitOfWork.ProjectRepository.All() 
            where project.IsActive 
            && project is Project 
            && (
              queryList.Contains(project.Name) 
             || project.Name.StartsWith(query) 
             || project.Name.Contains(query) 
             || project.Name.EndsWith(query) 
             || project.ProjectAddress.City.Name.StartsWith(query) 
             || project.ProjectAddress.City.Name.Contains(query) 
             || project.ProjectAddress.City.Name.EndsWith(query) 
             || queryList.Contains(project.ProjectAddress.City.Name) 
             || queryList.Contains(project.ProjectAddress.Address1) 
             ) 
            select project as Project).Distinct().AsParallel().ToList(); 

-Thanks

+0

你說的「物品」是什麼樣的?一個'List '和'List <>'自定義對象?你想要比較哪個字段?請詳細說明 – Franck 2014-09-10 11:52:09

+0

@Franck否其對象列表(模型) – 2014-09-10 12:33:04

+1

您應該實現一個方法,在'Project'類中實現部分@Sergey解決方案,該方法將接收查詢並檢查所需的所有屬性並計算匹配項。然後你只需做一個'var listOfProjectThatMatch = unitOfWork.ProjectRepository.All()。ToList()。其中​​(p => p.GetMatchesQuantity(「vishal pandey」)> 0).ToList()'然後用那個列表過濾掉你可以再次使用匹配數量或其他任何您想要按 – Franck 2014-09-10 12:44:30

回答

1

我會做的是創建一個custom comparer。 然後你創建一個實現這個接口的類。 在構造函數中,您可以傳遞預期字符串的列表。 在比較方法中,您可以根據項目具有多少預期字符串來比較兩個實例。

3

簡單(但不是很有效)解決方案僅僅是將大量的各種各樣的到您的項目:

var keywords = "vishal pandey"; 
var items = new[] { "pandey", "other", "vishal", "vishal pandey" }; 

var query = items.OrderByDescending(i => i.Contains(keywords)); 

foreach (var keyword in keywords.Split()) 
    query = query.ThenByDescending(i => i.Contains(keyword)); 

輸出:

vishal pandey 
vishal 
pandey 
other 

但是,如果你有很多的關鍵字,或者有很多項目,自定義比較器會更好解決方案。

UPDATE1:如果部分匹配的預定將不會是很重要的,你可以使用由弗蘭克建議這個簡單的解決方案:

var pattern = "vishal pandey".Replace(' ', '|'); 
var items = new[] { "pandey", "other", "vishal", "vishal pandey" };    
var query = items.OrderByDescending(i => Regex.Matches(i, pattern).Count); 

UPDATE2:自定義比較樣品

public class ItemsComparer : IComparer<string> 
{ 
    private string[] keywords; 
    private string pattern; 

    public ItemsComparer(string keywords) 
    { 
     this.keywords = keywords.Split(); 
     this.pattern = keywords.Replace(' ', '|'); 
    } 

    public int Compare(string x, string y) 
    { 
     var xMatches = Regex.Matches(x, pattern).Count; 
     var yMatches = Regex.Matches(y, pattern).Count; 

     if (xMatches != yMatches) 
      return yMatches.CompareTo(xMatches); 

     if (xMatches == keywords.Length || xMatches == 0) 
      return 0; 

     foreach (var keyword in keywords) 
     { 
      var result = y.Contains(keyword).CompareTo(x.Contains(keyword)); 
      if (result == 0) 
       continue; 

      return result; 
     } 

     return 0; 
    } 
} 

用法:

var items = new[] { "pandey", "other", "vishal", "vishal pandey" }; 
var comparer = new ItemsComparer("vishal pandey"); 
Array.Sort(items, comparer); 
+1

進行排序的命令。最佳做法是對字符串輸入的拆分進行匹配計數,然後按大多數匹配進行排序。 – Franck 2014-09-10 11:58:37

+0

@Franck同意,這也將有更好的排序項目有3個比賽中的2個。匹配唯一的問題是部分匹配的順序。例如。 'pandey'會在'vishal'之前出現在我的樣本中 – 2014-09-10 11:59:44

+0

是的,但我也在想這個訂單可能會變得很重要,所以匹配位置的評分系統可能會很好 – Franck 2014-09-10 12:02:10