#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. Это именно то, чего я хотел. Большое спасибо @-}—