2014-09-10 61 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