views:

55

answers:

1

Hello,

I have a specialized string dictionary of (string, string) (_RulesAndTheirDescriptions) that contains the name (key) and description (value) of methods in a given class. I currently do the following query to search for a match on the key or value and then bind that to a grid. Works great!

Dim Results = From v In _RulesAndTheirDescriptions _
 Where v.Value.ToString().ToUpper().Contains(Me.txtSearchFor.Text.ToUpper()) _
 Or v.Key.ToString().ToUpper().Contains(Me.txtSearchFor.Text.ToUpper()) _
 Order By v.Key _
 Select New With {.Rule = v.Key, .Description = v.Value.ToString()}

This works great when matching "word" or perhaps even "my word" but I would like to search for "my" and "word" and "also this". Meaning words and phrases seperated by spaces. Much like google and bing. When the user enters a value I only would require that the phrases be quoted. The following RegEx takes care of getting me a list word/phrase the user is looking for. Now I am having a hard time combining the the above query that works with the new enhanced list.

Please excuse the below code. I am just trying to test things and get it working.

Dim b As Match
b = Regex.Match(Me.txtSearchFor.Text, "(?<=(?:^|\s|,)"")[^""]*?(?="")|(?<=\s|^)(?!"")[\w\W]+?(?=\s|$)")

Dim sl As List(Of String) = New List(Of String)

If b.Success Then
    sl.Add(b.Value.ToUpper())

    Dim sMatch = b.NextMatch()

    While sMatch IsNot Nothing AndAlso sMatch.Success
        sl.Add(sMatch.Value.ToUpper())
        sMatch = sMatch.NextMatch()
    End While
End If

Per another post on this site I tried to do the following but that is not returing any results. I suspect because the sl.ToString() returns the type and not the value?

Dim Results = From v In _RulesAndTheirDescriptions _
 Where v.Value.ToString().ToUpper().Contains(sl.ToString()) _
 Order By v.Key _
 Select New With {.Rule = v.Key, .Description = v.Value.ToString()}

If I am going about this all wrong, please enlighten me. Seems like it should be easy.

Thanks in advance, Kevin

A: 

Hello You have to have a cross join to solve this problem

Dim Results = From v In _RulesAndTheirDescriptions _
join y in  sl on 1 equals 1 
 Where v.Value.ToString().ToUpper().Contains(y) _
 Order By v.Key _
 Select New With {.Rule = v.Key, .Description = v.Value.ToString()}

This can produce duplicates when more than one token can match a rule.So you can do a distinct if you want unique values

Like  Results.Distinct()
josephj1989
It sounds like it might work, but the second line: join y in sl on 1 equals 1Gives me the following error:You must reference at least one range variable on both sides of the 'Equals' operator. Range variable(s) 'v' must appear on one side of the 'Equals' operator, and range variable(s) 'y' must appear on the other.
Grandizer
Bot it works ok for me - I am using .NET 3.5 .For example the following works class Program { static void Main(string[] args) { List<string> x = new List<string>() { "AA", "BB", "CC" }; List<int> y = new List<int>() { 1, 2, 3 }; var z=from a in x join b in y on 1 equals 1 select new{X=a,Y=b}; foreach (var u in z) Console.WriteLine("{0} {1} ", u.X, u.Y); }GivesAA 1AA 2AA 3BB 1BB 2BB 3CC 1CC 2CC 3 }
josephj1989
OK Even if your version insists on "proper" values on either side you can overcome this by using something that equates to same value on both sides ex GetType() as belowvar z=from a in x join b in y on a.GetType() equals b.GetType() select new{X=a,Y=b};
josephj1989
Thank you for your efforts and enlightenment. I tryly appreciate it.
Grandizer