2014-09-10 7 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(); 

-Спасибо

+0

Как вы сказали, что такое «предмет»? a «Список » и «Список <>» пользовательского объекта? какое поле вы хотите сравнить? уточните больше, пожалуйста, – Franck

+0

@Franck no его список объектов (Model) –

+1

вы должны реализовать метод, реализующий частично решение @Sergey в классе 'Project', который получит запрос и проверит все свойства, которые вы хотите, и посчитайте совпадения. Затем вы просто выполняете 'var listOfProjectThatMatch = unitOfWork.ProjectRepository.All(). ToList(). Где (p => p.GetMatchesQuantity (" vishal pandey ")> 0) .ToList()' то с этим списком отфильтровывают вас может заказывать с использованием количества совпадений снова или что-либо еще, что вы хотите отсортировать по – Franck

ответ

1

Что бы я сделал, это создать custom comparer. Затем вы создаете класс, который реализует этот интерфейс IComparer<T>. В конструкторе вы можете передать список ожидаемых строк. В методе сравнения вы можете сравнить два экземпляра в зависимости от того, сколько из ожидаемых строк имеет элемент. Решение

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: Если порядок частичного совпадения не будет иметь важное значение, вы можете использовать это простое решение, предложенное Frank:

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

UPDATE2: Пользовательские образцы Comparer

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

+0

@Franck согласен, что также будет лучше сортировать предметы, которые имеют 2 из 3-х совпадений. Единственная проблема со спичками - порядок частичных совпадений. Например. 'pandey' будет идти до' vishal' для моего образца –

+0

Да, но я также думаю, что заказ может стать важным, поэтому система подсчета очков путем сопоставления позиции может быть хорошей – Franck

Смежные вопросы