Find similar product using linq

Viewed 293

I have a list of product. I want to select some similar products when I am in a product page using linq. For example, I'm in page of 'American English File Pre-intermediate'. and I have some product in db like below:

  • American English File Pre-intermediate
  • American English File Intermediate
  • American English File Pre-Advanced
  • American English File Pre-Advanced
  • American English File Beginner

What I tried to do:

  • split 'American English File Pre-intermediate' to string[].
  • I define int totalCount for size of string[].
  • filter for words that length are more than 3 (to eliminate some words like 'the' , 'and', 'or' ,...)
  • then I want to select product that in title has at least (2 or totalCount-1) common words with the split words.
  • below is what I used to test a solution with two list. but I prefer not to use 2 list.
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 && j>=2)
    {
        list2.Add(item);
    }
}

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

If you want to use Linq, you can do something like this:

// 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);
}

First you split the current product page and filter out the short words.
Then you go over all the products and:

  • you split the product
  • you find the matching words using the intersect
  • you filter for 2 or more matching words

You have to be careful with this approach, because it might have a big performance hit.
If you need to execute this multiple times, it's better to save the words separately. Then you only have to split the current page and compare with that.
Also be careful if you have a lot of products to search in.

Related