none
Search for strings in a list that contain specified words RRS feed

  • Question

  • Hi everyone

    I use extension method Where to filter a list

    IEnumerable<string> result = myList<string>.Where(s=>s.Contains(textBox1.Text));

    In the myList i have some strings i.e

    "a b c d", "c d e f" ,"a b e f", "d e f g"

    This works fine but requires me to provide words in specified order in textBox.  When i provide string " c d" i get "a b c d" and "c d e f"

    but i'd like to  get the same result when i provide "d c" and in addition string "d e f g" because 'd' is in it.

    What's the best way to do that?





    • Edited by PawelM Tuesday, July 3, 2012 7:07 PM
    Tuesday, July 3, 2012 6:56 PM

Answers

  • Find each item of the list which contains all the words to find.

    string[] wordsToFind = textBox1Text.Split();
    IEnumerable<string> result = myList.Where(s => wordsToFind.All(s.Split().Contains));

    • Marked as answer by PawelM Thursday, July 5, 2012 5:31 PM
    Thursday, July 5, 2012 4:45 PM

All replies

  • var result = myList.Where(str => str.Any( character => textBox1.Text.Contains(character) );
    If you are going to enter more than just a few characters in the list you should consider loading the textbox text into a HashSet, but for just a few characters it will be just fine as it is.
    • Proposed as answer by JohnGrove Tuesday, July 3, 2012 7:21 PM
    Tuesday, July 3, 2012 7:13 PM
  • I was just fiddling with this. My answer was just a tad more lengthy. Assume the variable "text" is your textBox1.Text

    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Text;
    using System.Text.RegularExpressions;

    namespace ConsoleApplication1
    {
        class Program
        {
            static void Main(string[] args)
            {
                String[] test = { "abcd", "cdef", "abef", "defg" };
                String text = "e";
                String[] result = test.Where(s =>
                    {
                        Boolean isInThere = true;
                        Char[] textArray = text.ToCharArray();
                        foreach (Char c in textArray)
                        {
                            if (!s.Contains(c))
                                isInThere = false;
                        }
                        return isInThere;
                    }).ToArray();
            }
        }
    }


    John Grove, Senior Software Engineer http://www.digitizedschematic.com/

    Tuesday, July 3, 2012 7:29 PM
  • @John, you could add a break in the 'if' statement of your 'for' loop.

    That's one of the advantages of using 'Any', you get the built in short circuiting.

    The converting to a char array is also not needed; string implements IEnumerable<char> all on it's own.

    Tuesday, July 3, 2012 7:42 PM
  • Yea, your example was much better. I was just trying to do it trying something different.

    John Grove, Senior Software Engineer http://www.digitizedschematic.com/

    Tuesday, July 3, 2012 8:07 PM
  • Could you tell me how to use HashSet in this case, because i might need to search longer strings?

    What if the List contains long strings (sentences) and i want to find all sentences that contain words written in TextBox?

    ie

    List<string> sentences = new List<string>();
    sentences.Add("This is a long sentence.");
    sentences.Add("This is another long sentence.");
    sentences.Add(...    //adding more sentences

    How to search  that list(the words in the TextBox are in custom order)?



    • Edited by PawelM Thursday, July 5, 2012 5:42 AM
    Thursday, July 5, 2012 5:30 AM
  • var searchWords = new HashSet<string>(textbox1.Text.Split(' '));
    var results = sentances.Where(sentance => sentance.Split(' ')
        .Any(word => searchWords.Contains(word)));

    Note that what you're doing won't scale particularly well, so if you have a lot of strings that you're searching this could get fairly slow.
    Thursday, July 5, 2012 1:28 PM
  • Find the items of myList for which there is at least 1 word among those from the textbox:

    IEnumerable<string> result = myList.Where(s => s.Split().Intersect(textBox1.Text.Split()).Any());

    Thursday, July 5, 2012 1:29 PM
  • var result = myList.Where(str => str.Any( character => textBox1.Text.Contains(character) );

    (str => str.Any(...)  ---> Any is not accessible after definisng a "str" parameter in VS 2008 and lower versions.

    At least I dont have it in the intellisence.


    Mitja

    Thursday, July 5, 2012 2:02 PM
  • (str => str.Any(...)  ---> Any is not accessible after definisng a "str" parameter in VS 2008 and lower versions.

    At least I dont have it in the intellisence.

    It compiles just fine in .NET 3.5 with VS 2010.
    Thursday, July 5, 2012 2:09 PM
  • Find the items of myList for which there is at least 1 word among those from the textbox:

    IEnumerable<string> result = myList.Where(s => s.Split().Intersect(textBox1.Text.Split()).Any());

    First off, you're splitting the textbox text with every single iteration.  You only need to split it once.  With this solution you're also adding its contents to a HashSet on every single string in the list, rather than just doing it once at the start.  
    Thursday, July 5, 2012 2:12 PM
  • Another question.

    IEnumerable<string> result = myList.Where(s => s.Split().Intersect(textBox1.Text.Split()).Any());

    This finds all strings contain at least one word from the TextBox but what when we want to find strings contain all words typed in TextBox

    Thursday, July 5, 2012 2:56 PM
  • First off, you're splitting the textbox text with every single iteration.  You only need to split it once. 

    Right. It's better to store the result of the split into a variable.

    Thursday, July 5, 2012 4:39 PM
  • Find each item of the list which contains all the words to find.

    string[] wordsToFind = textBox1Text.Split();
    IEnumerable<string> result = myList.Where(s => wordsToFind.All(s.Split().Contains));

    • Marked as answer by PawelM Thursday, July 5, 2012 5:31 PM
    Thursday, July 5, 2012 4:45 PM
  • what does "Contains" do in this case?
      Does it check if splitted string contains an element from wordsToFind?


    • Edited by PawelM Friday, July 6, 2012 11:15 AM
    Thursday, July 5, 2012 6:04 PM
  • My previous sample does the same thing as this one:
    string[] wordsToFind = textBox1Text.Split();
    IEnumerable<string> result = myList.Where(s => wordsToFind.All(w => s.Split().Contains(w)));

    Every time you want a delegate and write a lambda of the form x => foo(x) , you could simply use the method foo directly.
    Friday, July 6, 2012 12:18 PM