Skip to content
  • Categories
  • Recent
  • Tags
  • Popular
  • World
  • Users
  • Groups
Skins
  • Light
  • Cerulean
  • Cosmo
  • Flatly
  • Journal
  • Litera
  • Lumen
  • Lux
  • Materia
  • Minty
  • Morph
  • Pulse
  • Sandstone
  • Simplex
  • Sketchy
  • Spacelab
  • United
  • Yeti
  • Zephyr
  • Dark
  • Cyborg
  • Darkly
  • Quartz
  • Slate
  • Solar
  • Superhero
  • Vapor

  • Default (No Skin)
  • No Skin
Collapse
Code Project
  1. Home
  2. General Programming
  3. LINQ
  4. Trying to do a keyword search but not sure how to use the contains method [modified]

Trying to do a keyword search but not sure how to use the contains method [modified]

Scheduled Pinned Locked Moved LINQ
tutorialdatabasequestion
14 Posts 2 Posters 3 Views 1 Watching
  • Oldest to Newest
  • Newest to Oldest
  • Most Votes
Reply
  • Reply as topic
Log in to reply
This topic has been deleted. Only users with topic management privileges can see it.
  • D Dan Mos

    the .Contains() method is used to find items that Contain the specified "item". I would go for: 1) Predicate/Func or 2) A method like:

    public bool MyContains(string tags, string user){
    string[]separateWords = user.Split(" ");//just an example
    foreach(var str in separateWords){
    if(tags.Contains(str)){return true;}
    }
    return false;
    }

    If 2) change your where clause to something like this:

    where MyContains(o.tags, usewrTags)

    T Offline
    T Offline
    tonyonlinux
    wrote on last edited by
    #3

    Thanks. I used method two and it works perfectly. I have one more question to ask. how would I I make it search where it contains both words? I see here it does a foreach on the split string and sees if it is inside the o.whatever and it works like it should if i enter say coke it finds everything that has coke in it. but if i specifically wanted the to display items containing where both the words exist in any sequence how would that be done ? Like if i have tags pizza coke drinker and another tag eggs coke and i enter in the search coke drinker. with the method you showed it would pull up both records. but i only want the one where BOTH words match? I'm sorry for all the questions this is really new to me. Thanks for your help.

    D 1 Reply Last reply
    0
    • T tonyonlinux

      Thanks. I used method two and it works perfectly. I have one more question to ask. how would I I make it search where it contains both words? I see here it does a foreach on the split string and sees if it is inside the o.whatever and it works like it should if i enter say coke it finds everything that has coke in it. but if i specifically wanted the to display items containing where both the words exist in any sequence how would that be done ? Like if i have tags pizza coke drinker and another tag eggs coke and i enter in the search coke drinker. with the method you showed it would pull up both records. but i only want the one where BOTH words match? I'm sorry for all the questions this is really new to me. Thanks for your help.

      D Offline
      D Offline
      Dan Mos
      wrote on last edited by
      #4

      that's simple inverse the logic meaning

      foreach(vat srt in words){
      if (!tags.Contains(str)) {return false};
      }
      return true;//if it gets to this point means that it did not find a single word that is not
      //contained in the tags so all of them were found

      T 1 Reply Last reply
      0
      • D Dan Mos

        that's simple inverse the logic meaning

        foreach(vat srt in words){
        if (!tags.Contains(str)) {return false};
        }
        return true;//if it gets to this point means that it did not find a single word that is not
        //contained in the tags so all of them were found

        T Offline
        T Offline
        tonyonlinux
        wrote on last edited by
        #5

        well duh :( I feel really dumb on that one cause like you say that was simple. Thanks again for your help I really appreciate it.

        D 1 Reply Last reply
        0
        • T tonyonlinux

          well duh :( I feel really dumb on that one cause like you say that was simple. Thanks again for your help I really appreciate it.

          D Offline
          D Offline
          Dan Mos
          wrote on last edited by
          #6

          no problem. And DONT feel dumb. I almost screw up my career some time ago because I felt dumb and did not have the patiance to read tones of documentation. But I didn't. Because other help me(not in here CP but you got the ideea) ;)

          T 2 Replies Last reply
          0
          • D Dan Mos

            no problem. And DONT feel dumb. I almost screw up my career some time ago because I felt dumb and did not have the patiance to read tones of documentation. But I didn't. Because other help me(not in here CP but you got the ideea) ;)

            T Offline
            T Offline
            tonyonlinux
            wrote on last edited by
            #7

            Thanks, I will take your advice. I read a lot but sometimes the examples are poor or simply wrong. Also, i have a hard time comprehending things (always have just a part of my life). Anyway, thanks for your kind words.

            1 Reply Last reply
            0
            • D Dan Mos

              no problem. And DONT feel dumb. I almost screw up my career some time ago because I felt dumb and did not have the patiance to read tones of documentation. But I didn't. Because other help me(not in here CP but you got the ideea) ;)

              T Offline
              T Offline
              tonyonlinux
              wrote on last edited by
              #8

              Hey I know we have talked on this before. Still have an issue with it a little bit. What is happening is if i type in say lifeskills i will get a result for that. and also the match all works where if i typed in lifeskills christmas. That works perfectly the problem is it checks for the "whole word". Is there a way to check for instance if you type in lifeskill instead of lifeskills it will find it or if you type in say bear instead of bears ? here is what i have so far thanks for your previous help by the way...

                  public static IEnumerableGetbyKeywordLookup(string keywords)
                  {
                     
                         var results = from o in BookProxy.Readall()
                        //var results = from o in BookProxy.ReadallbyTags(keywords)
                                    where MyContains(o.TagName,keywords.Trim())
                                    
                                    select new GridProxy
                                    {
                                        Author = string.Format("{0} {1}", o.AuthorFirstname, o.AuthorSurname),
                                        AuthorID = o.AuthorID,
                                        AuthorFirst = o.AuthorFirstname,
                                        AuthorSurname = o.AuthorSurname,
                                        TagID = o.TagID,
                                        BookID = o.bookID,
                                        ISBN = o.ISBN,
                                        BookNumber = o.RefNumber,
                                        BookTitle = o.Title,
                                        Count = BookNumberProxy.getall().Count(c => c.BOOK\_ID == o.bookID)
                                    };
                         printerlist = results.ToList();
                      var distinct = results.GroupBy(o => o.ISBN).Select(o => o.FirstOrDefault());
                      return distinct.ToList();
                  }
              
                  public static IEnumerable GetbyKeywordLookupAll(string keywords)
                  {
                      
                      var results = from o in BookProxy.Readall()
                                    where MyContainsAll(o.TagName, keywords.Trim())
              
                                    select new GridProxy
                                    {
                                        Author = string.Format("{0} {1}", o.AuthorFirstname, o.AuthorSurname),
                                        AuthorID = o.AuthorID,
                                        AuthorFirst = o.AuthorFirstname,
                                        AuthorSurname = o.AuthorSurname,
                                        TagID = o.TagID,
                                        BookID = o.bookID,
                                        ISBN = o.ISBN,
              
              D 1 Reply Last reply
              0
              • T tonyonlinux

                Hey I know we have talked on this before. Still have an issue with it a little bit. What is happening is if i type in say lifeskills i will get a result for that. and also the match all works where if i typed in lifeskills christmas. That works perfectly the problem is it checks for the "whole word". Is there a way to check for instance if you type in lifeskill instead of lifeskills it will find it or if you type in say bear instead of bears ? here is what i have so far thanks for your previous help by the way...

                    public static IEnumerableGetbyKeywordLookup(string keywords)
                    {
                       
                           var results = from o in BookProxy.Readall()
                          //var results = from o in BookProxy.ReadallbyTags(keywords)
                                      where MyContains(o.TagName,keywords.Trim())
                                      
                                      select new GridProxy
                                      {
                                          Author = string.Format("{0} {1}", o.AuthorFirstname, o.AuthorSurname),
                                          AuthorID = o.AuthorID,
                                          AuthorFirst = o.AuthorFirstname,
                                          AuthorSurname = o.AuthorSurname,
                                          TagID = o.TagID,
                                          BookID = o.bookID,
                                          ISBN = o.ISBN,
                                          BookNumber = o.RefNumber,
                                          BookTitle = o.Title,
                                          Count = BookNumberProxy.getall().Count(c => c.BOOK\_ID == o.bookID)
                                      };
                           printerlist = results.ToList();
                        var distinct = results.GroupBy(o => o.ISBN).Select(o => o.FirstOrDefault());
                        return distinct.ToList();
                    }
                
                    public static IEnumerable GetbyKeywordLookupAll(string keywords)
                    {
                        
                        var results = from o in BookProxy.Readall()
                                      where MyContainsAll(o.TagName, keywords.Trim())
                
                                      select new GridProxy
                                      {
                                          Author = string.Format("{0} {1}", o.AuthorFirstname, o.AuthorSurname),
                                          AuthorID = o.AuthorID,
                                          AuthorFirst = o.AuthorFirstname,
                                          AuthorSurname = o.AuthorSurname,
                                          TagID = o.TagID,
                                          BookID = o.bookID,
                                          ISBN = o.ISBN,
                
                D Offline
                D Offline
                Dan Mos
                wrote on last edited by
                #9

                Hy,

                tonyonlinux wrote:

                Is there a way to check for instance if you type in lifeskill instead of lifeskills it will find it or if you type in say bear instead of bears ?

                Your methods are [Edit] NOT [/Edit] OK. [Edit] Don't split the tag(s) If you use List.Contains(item) it will call the Equals Method of the underling type in this case string. Ex:

                "Apples Oranges".Contains("Apple")=>true
                "Apples Oranges".Contains("Orange")=>true

                But myList.Add("Apples");
                myList.Add("Oranges");

                and then call myList.Contains("Apple") =>false

                [/Edit] Anyway: Suppose we have a tag of "My lions are eating lots of food". And user input "lion lot"; Well this code will find both of them and as a bonus return the hole word from tag => eg lions for lion and lots for lot.

                string tag = "My lions are eating lots of food";
                string user = "lion lot";

                List<String> matches = new List<string>();

                string[] words = user.Split(' ');
                foreach (var item in words)
                {
                if (tag.Contains(item))//it finds 'lion' in 'lions' and 'lot' in 'lots'
                {
                matches.Add(GetFullItem(tag, item));//returns the full word from the tags
                //eg lions for lion...
                }
                }

                //and here's a GetFullItem
                private string GetFullItem(string tag, string item)
                {
                //get start of the word (the location/index)
                int idxStrat = tag.IndexOf(item);
                //get the First Index of space after the start location for the current word
                //=>the idxEnd
                int idxEnd = tag.IndexOf(" ", idxStrat);
                //now get the length
                int length = idxEnd-idxStrat;
                //finally return the hole string( eg lions instead of lion and lots instead of lot
                return tag.Substring(idxStart,length);
                }

                modified on Sunday, March 7, 2010 10:36 AM

                T 1 Reply Last reply
                0
                • D Dan Mos

                  Hy,

                  tonyonlinux wrote:

                  Is there a way to check for instance if you type in lifeskill instead of lifeskills it will find it or if you type in say bear instead of bears ?

                  Your methods are [Edit] NOT [/Edit] OK. [Edit] Don't split the tag(s) If you use List.Contains(item) it will call the Equals Method of the underling type in this case string. Ex:

                  "Apples Oranges".Contains("Apple")=>true
                  "Apples Oranges".Contains("Orange")=>true

                  But myList.Add("Apples");
                  myList.Add("Oranges");

                  and then call myList.Contains("Apple") =>false

                  [/Edit] Anyway: Suppose we have a tag of "My lions are eating lots of food". And user input "lion lot"; Well this code will find both of them and as a bonus return the hole word from tag => eg lions for lion and lots for lot.

                  string tag = "My lions are eating lots of food";
                  string user = "lion lot";

                  List<String> matches = new List<string>();

                  string[] words = user.Split(' ');
                  foreach (var item in words)
                  {
                  if (tag.Contains(item))//it finds 'lion' in 'lions' and 'lot' in 'lots'
                  {
                  matches.Add(GetFullItem(tag, item));//returns the full word from the tags
                  //eg lions for lion...
                  }
                  }

                  //and here's a GetFullItem
                  private string GetFullItem(string tag, string item)
                  {
                  //get start of the word (the location/index)
                  int idxStrat = tag.IndexOf(item);
                  //get the First Index of space after the start location for the current word
                  //=>the idxEnd
                  int idxEnd = tag.IndexOf(" ", idxStrat);
                  //now get the length
                  int length = idxEnd-idxStrat;
                  //finally return the hole string( eg lions instead of lion and lots instead of lot
                  return tag.Substring(idxStart,length);
                  }

                  modified on Sunday, March 7, 2010 10:36 AM

                  T Offline
                  T Offline
                  tonyonlinux
                  wrote on last edited by
                  #10

                  so your are saying do this ?

                  private static bool MyContains(string tags, string user)
                  {

                          List seperatewords = new List(user.Split(' ').ToList());
                          List seperateTags = new List(tags.Split(' ').ToList());
                          //new
                          List matches = new List();
                          foreach (var str in seperatewords)
                          {
                              string stringvalue = str.ToString();
                              //new 
                              if (tags.Contains(str))
                              {
                                  matches.Add(GetfullText(tags, str));
                                  
                              }
                  
                              //end new
                              //original  if (seperateTags.Contains(str, StringComparer.CurrentCultureIgnoreCase)) { return true; }
                              if (tags.Contains(matches.ToString(), StringComparer.CurrentCultureIgnoreCase)) { return true; }
                          }
                          return false;
                      }
                  
                      private static string GetfullText(string tags, string str)
                      {
                          //get start of the word (the location/index)
                          int idxStrat = tags.IndexOf(str);
                          //get the First Index of space after the start location for the current word
                          //=>the idxEnd
                          int idxEnd = tags.IndexOf(" ", idxStrat);
                          //now get the length
                          int length = idxEnd - idxStrat;
                          //finally return the hole string( eg lions instead of lion and lots instead of lot
                          return tags.ToString().Substring(idxStrat, length); ;
                      }
                  

                  :( i'm confused still sorry

                  D 1 Reply Last reply
                  0
                  • T tonyonlinux

                    so your are saying do this ?

                    private static bool MyContains(string tags, string user)
                    {

                            List seperatewords = new List(user.Split(' ').ToList());
                            List seperateTags = new List(tags.Split(' ').ToList());
                            //new
                            List matches = new List();
                            foreach (var str in seperatewords)
                            {
                                string stringvalue = str.ToString();
                                //new 
                                if (tags.Contains(str))
                                {
                                    matches.Add(GetfullText(tags, str));
                                    
                                }
                    
                                //end new
                                //original  if (seperateTags.Contains(str, StringComparer.CurrentCultureIgnoreCase)) { return true; }
                                if (tags.Contains(matches.ToString(), StringComparer.CurrentCultureIgnoreCase)) { return true; }
                            }
                            return false;
                        }
                    
                        private static string GetfullText(string tags, string str)
                        {
                            //get start of the word (the location/index)
                            int idxStrat = tags.IndexOf(str);
                            //get the First Index of space after the start location for the current word
                            //=>the idxEnd
                            int idxEnd = tags.IndexOf(" ", idxStrat);
                            //now get the length
                            int length = idxEnd - idxStrat;
                            //finally return the hole string( eg lions instead of lion and lots instead of lot
                            return tags.ToString().Substring(idxStrat, length); ;
                        }
                    

                    :( i'm confused still sorry

                    D Offline
                    D Offline
                    Dan Mos
                    wrote on last edited by
                    #11

                    No I, saying to do this:

                    private static bool MyContains(string tags, string user)
                    {
                    List seperatewords = new List(user.Split(' ').ToList());
                    //List seperateTags = new List(tags.Split(' ').ToList());//get rid of this
                    foreach (var str in seperatewords)
                    {
                    string stringvalue = str.ToString();
                    if (tags.Contains(str))
                    {
                    //matches.Add(...) this is optional just an example but you don't really need it
                    return true;
                    }
                    }
                    return false;

                    T 2 Replies Last reply
                    0
                    • D Dan Mos

                      No I, saying to do this:

                      private static bool MyContains(string tags, string user)
                      {
                      List seperatewords = new List(user.Split(' ').ToList());
                      //List seperateTags = new List(tags.Split(' ').ToList());//get rid of this
                      foreach (var str in seperatewords)
                      {
                      string stringvalue = str.ToString();
                      if (tags.Contains(str))
                      {
                      //matches.Add(...) this is optional just an example but you don't really need it
                      return true;
                      }
                      }
                      return false;

                      T Offline
                      T Offline
                      tonyonlinux
                      wrote on last edited by
                      #12

                      thanks for your help but it is still not working. I tried what you posted above. but i get no results what so ever now. I think it has something to do with not having the stringcomparer.cultureignorecase in there. I tried to put it back in there but it doesn't like the fact that tags is not that of a list :(

                      D 1 Reply Last reply
                      0
                      • D Dan Mos

                        No I, saying to do this:

                        private static bool MyContains(string tags, string user)
                        {
                        List seperatewords = new List(user.Split(' ').ToList());
                        //List seperateTags = new List(tags.Split(' ').ToList());//get rid of this
                        foreach (var str in seperatewords)
                        {
                        string stringvalue = str.ToString();
                        if (tags.Contains(str))
                        {
                        //matches.Add(...) this is optional just an example but you don't really need it
                        return true;
                        }
                        }
                        return false;

                        T Offline
                        T Offline
                        tonyonlinux
                        wrote on last edited by
                        #13

                        nevermind i think i got it it looks like i did anyway when i ran some test. I simply took and did the following on the if statement.

                        if (tags.toUpper().Contains(str.ToUpper))
                        {
                        return true;
                        }

                        thanks again

                        1 Reply Last reply
                        0
                        • T tonyonlinux

                          thanks for your help but it is still not working. I tried what you posted above. but i get no results what so ever now. I think it has something to do with not having the stringcomparer.cultureignorecase in there. I tried to put it back in there but it doesn't like the fact that tags is not that of a list :(

                          D Offline
                          D Offline
                          Dan Mos
                          wrote on last edited by
                          #14

                          OK. Maybe I understood you wrong. Here's what I think you need to acomplish => correct me if I'm wrong. So, you need to get like all the data about books based on the book keywords/tags and the keywords introduced by user. If that's what you need then this is a working solution: (feel free to create a new windows app, add 2 buttons and paste the code to check):

                          /// <summary>
                          /// check if contains any keywords
                          /// </summary>
                          /// <param name="sender"></param>
                          /// <param name="e"></param>
                          private void btnContainsAny_Click(object sender, EventArgs e)
                          {
                          string tags = "science fiction futurist 1024 cores 25 GHz";
                          string user = "fiction core";
                          if (MyContainsAny(tags, user))
                          {
                          string message =
                          String.Format("At least one keyword form \"{0}\" was found in \r\n" +
                          "\"{1}\"", user, tags);
                          MessageBox.Show(message);
                          }
                          }

                              /// <summary>
                              /// check if contains all keywords
                              /// </summary>
                              /// <param name="sender"></param>
                              /// <param name="e"></param>
                              private void btnContainsAll\_Click(object sender, EventArgs e)
                              {
                                  string tags = "science fiction futurist 1024 cores 25 GHz";
                                  string user = "fiction core";
                                  if (MyContainsAll(tags, user))
                                  {
                                      string message =
                                          String.Format("All the keywords form \\"{0}\\" were found in \\r\\n" +
                                          "\\"{1}\\"", user, tags);
                                      MessageBox.Show(message);//as you can see it finds core in cores
                                  }
                              }        
                          
                          
                              /// <summary>
                              /// used to see if the tag contains ANY of the keywords introduced by user
                              /// </summary>
                              /// <param name="tag"></param>
                              /// <param name="userData"></param>
                              /// <returns></returns>
                              private bool MyContainsAny(string tag, string userData)
                              {
                                  string\[\] words = userData.Trim().Split(" ");
                                  foreach (var item in words)
                                  {
                                      if (tag.Contains(item)) { return true; }
                                  }
                                  return false;
                              }
                          
                              /// <summary>
                              /// used to see if the tag contains ALL of the keywords introduced by user
                              /// </
                          
                          1 Reply Last reply
                          0
                          Reply
                          • Reply as topic
                          Log in to reply
                          • Oldest to Newest
                          • Newest to Oldest
                          • Most Votes


                          • Login

                          • Don't have an account? Register

                          • Login or register to search.
                          • First post
                            Last post
                          0
                          • Categories
                          • Recent
                          • Tags
                          • Popular
                          • World
                          • Users
                          • Groups