BASit Bulbulia
asked on
How to search for part of a dictionary key (.net vb visual studio 2008)
Could someone please tell me, how I can search for only a part of a key in a dictionary (in VB.NET)?
I use the following sample code:
Dim PriceList As New Dictionary(Of String, Double)
PriceList.Add("Spaghetti alla carbonara", 21.65)
PriceList.Add("Spaghetti aglio e olio", 22.65)
PriceList.Add("Spaghetti alla napoletana", 23.65)
PriceList.Add("Spaghetti alla puttanesca ", 24.65)
PriceList.Add("Spaghetti alla gricia ", 25.65)
PriceList.Add("Spaghetti alle vongole", 26.65)
PriceList.Add("Spaghetti Bolognese", 27.65)
If PriceList.ContainsKey("spa ghetti bolognese") Then
Dim price As Double = PriceList.Item("spaghetti bolognese")
Console.WriteLine("Found, price: " & price)
End If
If Not PriceList.ContainsKey("Bol ognese") Then
Console.WriteLine("How can I search for only a part of a key?")
End If
If I only know a part of the key like "Bolognese" or just a part of word like "Bolo", how can I search for this part in the complete key?
I use the following sample code:
Dim PriceList As New Dictionary(Of String, Double)
PriceList.Add("Spaghetti alla carbonara", 21.65)
PriceList.Add("Spaghetti aglio e olio", 22.65)
PriceList.Add("Spaghetti alla napoletana", 23.65)
PriceList.Add("Spaghetti alla puttanesca ", 24.65)
PriceList.Add("Spaghetti alla gricia ", 25.65)
PriceList.Add("Spaghetti alle vongole", 26.65)
PriceList.Add("Spaghetti Bolognese", 27.65)
If PriceList.ContainsKey("spa
Dim price As Double = PriceList.Item("spaghetti bolognese")
Console.WriteLine("Found, price: " & price)
End If
If Not PriceList.ContainsKey("Bol
Console.WriteLine("How can I search for only a part of a key?")
End If
If I only know a part of the key like "Bolognese" or just a part of word like "Bolo", how can I search for this part in the complete key?
You'll find the answer in the question you asked at that other site.
SOLUTION
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
ASKER
@webtubbs - > The solution at the other site does not work as the Pricelist.where (generates an error) -> for those who are interested in finding a better solution or have a work around the error - please visit :-
http://stackoverflow.com/q uestions/1 7998321/ho w-to-searc h-for-a-pa rt-of-a-di ctionary-k ey
@James Burger -> Your method requires a loop through the whole array and it ain't efficient and defeats the purpose of the dictionary hash.
http://stackoverflow.com/q
@James Burger -> Your method requires a loop through the whole array and it ain't efficient and defeats the purpose of the dictionary hash.
A Hash is a numeric or condensed representation of a specific string in its whole. Entries in the directory are sorted by that hash, so this is why it is efficient. It is useful to search for the whole string, but otherwise worthless.
It's a bit similar as an index on a string value in a database. Search for the whole content of the field, and it zips through. But as soon as you start looking for anything that is not the beginning of the string, by the use of LIKE for instance, you defeats its purpose because the index becomes useless.
It's a bit similar as an index on a string value in a database. Search for the whole content of the field, and it zips through. But as soon as you start looking for anything that is not the beginning of the string, by the use of LIKE for instance, you defeats its purpose because the index becomes useless.
Hi compubyte-sa;
Try the code snippet below, it should give you what you need.
Try the code snippet below, it should give you what you need.
Dim searchTerm As String = "Bolo"
Dim price As KeyValuePair(Of String, Double) = PriceList.Where(Function(k) k.Key.Contains(searchTerm)).FirstOrDefault()
If price.Key IsNot Nothing Then
Console.WriteLine("Found, price: " + price.Value.ToString() )
End If
ASKER
@Fernando - I have used this code before and in Visual Studio .net 2008 I get an error -> Error 1 'Where' is not a member of 'System.Collections.Generi c.Dictiona ry(Of String, Integer)'.
Pic enclosed !
Full code below :-
Pic enclosed !
Full code below :-
Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click
Dim DealDetail As New Dictionary(Of String, Integer)
Dim x As Integer = 0
Dim ffile As String = "\ums\dealdetail.csv"
Dim f As Integer = FreeFile()
If File.Exists(ffile) Then
FileOpen(f, ffile, OpenMode.Input)
While EOF(f) = False
x = x + 1
DealDetail.Add(LineInput(f) + Str(x), x)
' Dim items() As String = Split(tzz, ";")
End While
FileClose(f)
End If
Dim PriceList As New Dictionary(Of String, Integer)
x = 0
ffile = "\ums\pricelist.csv"
f = FreeFile()
If File.Exists(ffile) Then
FileOpen(f, ffile, OpenMode.Input)
While EOF(f) = False
x = x + 1
PriceList.Add(LineInput(f) + Str(x), x)
' Dim items() As String = Split(tzz, ";")
End While
FileClose(f)
End If
Dim Product As New Dictionary(Of String, Integer)
x = 0
ffile = "\ums\product.csv"
f = FreeFile()
If File.Exists(ffile) Then
FileOpen(f, ffile, OpenMode.Input)
While EOF(f) = False
x = x + 1
Product.Add(LineInput(f) + Str(x), x)
' Dim items() As String = Split(tzz, ";")
End While
FileClose(f)
End If
Dim Suppliers As New Dictionary(Of String, Integer)
ffile = "\ums\suppliers.csv"
f = FreeFile()
If File.Exists(ffile) Then
FileOpen(f, ffile, OpenMode.Input)
While EOF(f) = False
x = x + 1
Suppliers.Add(LineInput(f) + Str(x), x)
' Dim items() As String = Split(tzz, ";")
End While
FileClose(f)
End If
x = 0
Dim y As Integer
Dim Z As Integer
Dim ZZ As Integer
Dim DiscountValue As Single
Dim DiscountPercentage As Single
Dim PriceN As Single
Dim Sup As String
Dim FoundItem As Boolean = False
Dim pair As KeyValuePair(Of String, Integer)
For Each pair In DealDetail
Sup = "Unknown"
FoundItem = False
Label1.Text = Str(pair.Value) + " of" + Str(DealDetail.Count)
Application.DoEvents()
Dim items() As String = Split(pair.Key, ";")
StartDate.Add(items(4))
EndDate.Add(items(5))
DiscountValue = Val(items(11))
DiscountPercentage = Val(items(12))
Dim searchTerm As String = "Bolo"
Dim price As KeyValuePair(Of String, Single) = Product.Where(Function(k) k.Key.Contains(searchTerm)).FirstOrDefault()
If price.Key IsNot Nothing Then
Console.WriteLine("Found, price: " + price.Value.ToString())
End If
If Product.ContainsKey(items(3)) Then
MsgBox("Found ! ! ! ")
End If
Next
error.where.jpg
Where appeared in framework 3.5. If you are targeting an older version, it's not there.
Anyway, what do you think Where does in the background?
If you know about hashtables, you know that it needs to loop through the items until it finds one whose key contains the substring you are looking for. There is no way to use the optimisation of the hash in any kind of hashtable unless you look for the whole key.
Anyway, what do you think Where does in the background?
If you know about hashtables, you know that it needs to loop through the items until it finds one whose key contains the substring you are looking for. There is no way to use the optimisation of the hash in any kind of hashtable unless you look for the whole key.
Let's look at what has been recommended here:
Draw your own conclusions but James still has the better method.
-saige-
Module Module1
Private ReadOnly watch As New Stopwatch()
Private ReadOnly PriceList As New Dictionary(Of String, Double)() From {{"Spaghetti alla carbonara", 21.65}, {"Spaghetti aglio e olio", 22.65}, {"Spaghetti alla napoletana", 23.65}, {"Spaghetti alla puttanesca ", 24.65}, {"Spaghetti alla gricia ", 25.65}, {"Spaghetti alle vongole", 26.65}, {"Spaghetti Bolognese", 27.65}}
Sub Main()
Console.WriteLine("Let's do some calculations:")
DictionaryWhere()
KeyWhere()
StandardFor()
Console.ReadLine()
End Sub
Sub DictionaryWhere()
Console.WriteLine()
Console.WriteLine("Using a dictionary based where clause")
watch.Reset()
watch.Start()
Dim result As KeyValuePair(Of String, Double) = PriceList.Where(Function(k) k.Key.Contains("Bologne")).FirstOrDefault()
watch.Stop()
If Not String.IsNullOrEmpty(result.Key) Then
Console.WriteLine("Found: {0} for {1}", result.Key, result.Value)
Else
Console.WriteLine("Could not find search item")
End If
Console.WriteLine("Using a dictionary based where clause took {0} ms", watch.ElapsedMilliseconds)
End Sub
Sub KeyWhere()
Console.WriteLine()
Console.WriteLine("Using a key based where clause")
watch.Reset()
watch.Start()
Dim result As KeyValuePair(Of String, Double) = (From item In PriceList Where item.Key.Contains("Bologne") Select item).FirstOrDefault()
watch.Stop()
If Not String.IsNullOrEmpty(result.Key) Then
Console.WriteLine("Found: {0} for {1}", result.Key, result.Value)
Else
Console.WriteLine("Could not find search item")
End If
Console.WriteLine("Using a key based where clause took {0} ms", watch.ElapsedMilliseconds)
End Sub
Sub StandardFor()
Console.WriteLine()
Console.WriteLine("Using a standard forloop")
watch.Reset()
watch.Start()
Dim result As New KeyValuePair(Of String, Double)
With PriceList
For i As Integer = 0 To .Keys.Count - 1
If .Keys(i).IndexOf("Bologne") > -1 Then
result = .ElementAt(i)
Exit For
End If
Next
End With
watch.Stop()
If Not String.IsNullOrEmpty(result.Key) Then
Console.WriteLine("Found: {0} for {1}", result.Key, result.Value)
Else
Console.WriteLine("Could not find search item")
End If
Console.WriteLine("Using a standard forloop took {0} ms", watch.ElapsedMilliseconds)
End Sub
End Module
Which produces the following output (results will vary) -As you can see here, the for loop (which is really what linq does when you come down to it), performs this search a millisecond faster than the key based search. The key based search is, essentially, an expanded expression based statement that does the same lookup as using the Method based dictionary.Where lookup.Draw your own conclusions but James still has the better method.
-saige-
ASKER
@saige - thank you for response - it does show that James method is the fastest !
it does show that James method is the fastestIt does show that net framework cash queries. Try
Sub Main()
Console.WriteLine("Let's do some calculations:")
StandardFor()
KeyWhere()
DictionaryWhere()
Console.ReadLine()
End Sub
A slightly changed code
Module Module1
Private ReadOnly watch As New Stopwatch()
Private ReadOnly PriceList As New Dictionary(Of String, Double)() From {{"Spaghetti alla carbonara", 21.65}, {"Spaghetti aglio e olio", 22.65}, {"Spaghetti alla napoletana", 23.65}, {"Spaghetti alla puttanesca ", 24.65}, {"Spaghetti alla gricia ", 25.65}, {"Spaghetti alle vongole", 26.65}, {"Spaghetti Bolognese", 27.65}}
Private result As KeyValuePair(Of String, Double)
Private passes As Integer = 100000
Sub Main()
Console.WriteLine("Let's do some calculations:")
KeyWhere()
DictionaryWhere()
StandardFor()
Console.ReadLine()
End Sub
Sub DictionaryWhere()
result = New KeyValuePair(Of String, Double)
watch.Reset()
watch.Start()
For i = 1 To passes
result = PriceList.Where(Function(k) k.Key.Contains("Bologne")).FirstOrDefault()
Next
watch.Stop()
Console.WriteLine("Using a dictionary based where clause took {0} ms", watch.ElapsedMilliseconds)
End Sub
Sub KeyWhere()
result = New KeyValuePair(Of String, Double)
watch.Reset()
watch.Start()
For i = 1 To passes
Dim key = (From x In PriceList.Keys Where x.Contains("Bologne")).FirstOrDefault
result = New KeyValuePair(Of String, Double)(key, PriceList(key))
Next
Console.WriteLine("Using a key based where clause took {0} ms", watch.ElapsedMilliseconds)
End Sub
Sub StandardFor()
result = New KeyValuePair(Of String, Double)
watch.Reset()
watch.Start()
For j = 1 To passes
With PriceList
For i As Integer = 0 To .Keys.Count - 1
If .Keys(i).IndexOf("Bologne") > -1 Then
result = .ElementAt(i)
Exit For
End If
Next
End With
Next
watch.Stop()
Console.WriteLine("Using a standard forloop took {0} ms", watch.ElapsedMilliseconds)
End Sub
End Module
ASKER
@Ark Ummmm very interesting ! !
ASKER CERTIFIED SOLUTION
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
ASKER
Thanks guys ! !