Найти похожий продукт с помощью linq

#c# #asp.net #sql-server #linq #model-view-controller

#c# #asp.net #sql-сервер #linq #модель-представление-контроллер

Вопрос:

У меня есть список продуктов. Я хочу выбрать несколько похожих продуктов, когда я нахожусь на странице продукта с помощью linq. Например, я нахожусь на странице ‘American English File Pre-intermediate’. и у меня есть какой-то продукт в базе данных, как показано ниже:

  • Американский английский файл Pre-intermediate
  • Американский файл английского языка Intermediate
  • Файл на американском английском языке Предварительно расширен
  • Файл на американском английском языке Предварительно расширен
  • Начинающий программист по американскому английскому

Что я пытался сделать:

  • разделите ‘American English File Pre-intermediate’ на строку[].
  • Я определяю значение int totalCount для размера строки[].
  • отфильтруйте слова длиной более 3 (чтобы исключить некоторые слова, такие как ‘the’, ‘and’, ‘or’, …)
  • затем я хочу выбрать продукт, в названии которого есть как минимум (2 или totalCount-1) общие слова с разделенными словами.
  • ниже приведено то, что я использовал для тестирования решения с двумя списками. но я предпочитаю не использовать список 2.
 List<string> list = new List<string>();
List<string> list2 = new List<string>();
list.Add("english file pre-intermediate 2 the");
list.Add("english file intermediate 2 the");
list.Add("english file pre-advanced 2 the");
list.Add("english file advanced 2 the");
list.Add("english file beginner 2 the");
list.Add("english file");
list.Add("english file beginner 2 the");
list.Add("english file");
var words = textBox1.Text.Split(' ');
label1.Text = words.Length.ToString();
string res = "";
foreach (var item in words)
{
    if (item.Length>3)
    {
        res = res   "-";
    }
}

int total = words.Where(p => p.Length > 3).Count();
var fwords = words.Where(p => p.Length > 3).OrderBy(p=>p);

foreach (var item in list)
{
    int i = 0;
    int j = 0;
    foreach (var w in fwords)
    {
        if (item.ToLower().Contains(w.ToLower()))
        {
            j  ;
        }
        else
        {
            i--;
        }
        
    }

    if (i>=-1 amp;amp; j>=2)
    {
        list2.Add(item);
    }
}

var res2 = "";
foreach (var item in list2)
{
    res2 = res2   item   "---";
}
label2.Text = res2;
  

Комментарии:

1. Попробуйте нечеткое сопоставление, например github.com/JakeBayer/FuzzySharp

2. var res = words.Where( w => w.Length> 3).Aggregate("-",(current, next)=> current "-" );

3. int total = res.Length;

Ответ №1:

Если вы хотите использовать Linq, вы можете сделать что-то вроде этого:

 // setup
var products = new List<string>
{
    "American English File Pre-intermediate",
    "British English Word Intermediate",
    "American English File Pre-Advanced",
    "British English Word Pre-Advanced",
    "British English File Beginner"
};
var currentProductPage = products[0];

// split and filter short words
var currentProductWords = currentProductPage.Split(' ').Where(product => product.Length > 3);

// Find two ore more matching words
var productsMatchingTwoOrMoreWords = products.Where(product => product.Split(' ').Intersect(currentProductWords).Count() >= 2);

// Display result
foreach (var matchingProducts in productsMatchingTwoOrMoreWords)
{
    Console.WriteLine(matchingProducts);
}
  

Сначала вы разбиваете текущую страницу продукта и отфильтровываете короткие слова.
Затем вы просматриваете все продукты и:

  • вы разделяете продукт
  • вы находите совпадающие слова с помощью intersect
  • выполняется фильтрация по двум или более совпадающим словам

Вы должны быть осторожны с этим подходом, потому что это может привести к значительному снижению производительности.
Если вам нужно выполнить это несколько раз, лучше сохранить слова по отдельности. Затем вам нужно только разделить текущую страницу и сравнить с ней.
Также будьте осторожны, если у вас много продуктов для поиска.

Комментарии:

1. Это именно то, чего я хотел. Большое спасибо @-}—