How to use Dictionary in VB.net? - asp.net

I have written this function to auto correct gender to M or F from different values in a string array. It works fine but my manager told me to use Dictionary which he said is more efficient. But I have no idea. Anyone like to help me to understand how this can be done ? Thanks.
Public Function AutoGender(ByVal dt As DataTable) As DataTable
Dim Gender As String = ""
Dim Mkeywords() As String = {"boy", "boys", "male", "man", "m", "men", "guy"}
Dim Fkeywords() As String = {"girl", "girls", "female", "woman", "f", "women", "chick"}
Dim row As DataRow
For Each row In dt.Rows
If Mkeywords.Contains(row("Gender").ToString.ToLower) Then
Gender = "M"
row("Gender") = Gender
ElseIf Fkeywords.Contains(row("Gender").ToString.ToLower) Then
Gender = "F"
row("Gender") = Gender
End If
Next
Return dt
End Function

Here is an example how you could implement the Dictionary(Of String, String) to lookup whether this synonym is known or not:
Shared GenderSynonyms As Dictionary(Of String, String) = New Dictionary(Of String, String) From
{{"boy", "M"}, {"boys", "M"}, {"male", "M"}, {"man", "M"}, {"m", "M"}, {"men", "M"}, {"guy", "M"},
{"girl", "F"}, {"girls", "F"}, {"female", "F"}, {"woman", "F"}, {"f", "F"}, {"women", "F"}, {"chick", "F"}}
Public Function AutoGender(ByVal dt As DataTable) As DataTable
If dt.Columns.Contains("Gender") Then
For Each row As DataRow In dt.Rows
Dim oldGender = row.Field(Of String)("Gender").ToLower
Dim newGender As String = String.Empty
If GenderSynonyms.TryGetValue(oldGender, newGender) Then
row.SetField("Gender", newGender)
End If
Next
End If
Return dt
End Function
Note that i've used the collection initializer to fill the Dictionary that is a convenient way to use literals to initialize collections. You could also use the Add method.
Edit: Just another approach that might be more concise is using two HashSet(Of String), one for the male synonyms and one for the female:
Shared maleSynonyms As New HashSet(Of String) From
{"boy", "boys", "male", "man", "m", "men", "guy"}
Shared femaleSynonyms As New HashSet(Of String) From
{"girl", "girls", "female", "woman", "f", "women", "chick"}
Public Function AutoGender(ByVal dt As DataTable) As DataTable
If dt.Columns.Contains("Gender") Then
For Each row As DataRow In dt.Rows
Dim oldGender = row.Field(Of String)("Gender").ToLower
Dim newGender As String = String.Empty
If maleSynonyms.Contains(oldGender) Then
row.SetField("Gender", "M")
ElseIf femaleSynonyms.Contains(oldGender) Then
row.SetField("Gender", "F")
End If
Next
End If
Return dt
End Function
A HashSet must also be unique, so it cannot contain duplicate Strings (like the key in the Dictionary), but it's not a key-value pair but only a set.

Simply change both of your arrays to dictionaries, and do a ContainsKey instead of Contains.
Dim Mkeywords = New Dictionary(Of String, String) From
{{"boy", ""}, {"boys", ""}, {"male", ""}, {"man", ""}, {"m", ""}, {"men", ""}, {"guy", ""}}
(and follow suit for the female)
However, as you might've noticed I put in all those empty strings. This is because dictionaries have values as well as keys, but since we're not using the values, I made them empty strings. To have the same O(1) lookup but avoiding all the extraneous values, you can use a HashSet in a similar manner.
All you have to change now is, like I said, use ContainsKey (or for HashSet if you go that route, it's still just Contains):
If Mkeywords.ContainsKey(row("Gender").ToString.ToLower) Then
One final note: this will only be "more efficient" if the data starts growing in size considerably. Right now as you have it, with only those few elements, it may even be slower to use a dictionary.

Related

Replace and Contains not recognizing the string

I am trying to strip the country code off the phone number and place it in the textbox txtMobile. cCode is just an empty string.
GlobalsFSiA.COUNTRY_CODES.Split(",") contains +44 and +353.
The phone number I am testing with is +353861234567
For Each code As String In GlobalsFSiA.COUNTRY_CODES.Split(",")
If objEmployee.MobilePhone.Contains(code) Then
cCode = code
End If
Next
Dim number As String = objEmployee.MobilePhone.Replace(cCode, "0")
txtMobile.Text = number
First you have to search for What is actually the split() method is used for and also difference between split() and substring():
I think Substring() is more suitable in this scenario, you can code like this for extracting country code from the given number:
Dim mobileNumber As String = "+353861234567"
Dim countryCode As String = mobileNumber.Substring(0, 3)
using this code I do get the correct result
Dim sTest As String = "+353861234567"
Dim cCode As String = ""
Dim numbers As New List(Of String)()
numbers.Add("+44")
numbers.Add("+353")
For Each code As String In numbers
If sTest.Contains(code) Then
cCode = code
End If
Next
Dim number As String = sTest.Replace(cCode, "0")
Is the cCode declared internally? Might be an option to take the value from the object before parsing it

how to split array data in vb.net?

I have a datatable that returns a column name location which is a combination of city,state and zipcode,i have stored that column values in an array. now i want to split the array data and store in another array.
here is the code but it is not working.
Dim eTemp As DataTable = dt.DefaultView.ToTable(True, "Location")
Dim s() As String
Dim Count As Integer = PortCodeTemp.Rows.Count - 1
ReDim s(0 To Count)
For i = 0 To Count
s(i) = PortCodeTemp.Rows(i).Item("Location")
For t As Integer = 0 To Count
Dim items As String() = s.Split(",".ToCharArray())
Next
Next
Your issue is here
Dim items As String() = s.Split(",".ToCharArray())
because there is no Split method for an array.
I think you meant to split the string at index i, which is where you stored the string value of location.
Dim items As String() = s(i).Split(",".ToCharArray())
Update
I'm not sure why you're doing it this way but here is something you can try. Instead of using an array I just used a List(Of String) so there's no need to be doing a redim in every loop.
Dim allItems As New List(Of String)
For i = 0 To PortCodeTemp.Rows.Count - 1
Dim location as String = PortCodeTemp.Rows(i).Item("Location")
allItems.AddRange(location.Split(",".ToCharArray()))
Next
Therefore, allItems should contain everything.

LINQ - Putting result in a dictionary(Of String, Integer), where the integer must be 0

I have a LINQ2Entity problem, I want to get the value, string, from a database, so I select FProducts.Serial_number, and to end the query, I do .ToDictionary.
The problem is, it tells me that it doesn't have sufficient parameters, to convert ToDictionary.
So I need something like select FProducts.Serial_number, Nothing). ToDictionary.
Also FProducts.Serial_number, 0).ToDictionary doesn't work.
Any recommendations?
Sub GetStatistics(ByVal ProductNumbers As List(Of String), ByRef Passed As Integer, ByRef FailedProducts As List(Of String))
Passed = 0
FailedProducts = Nothing
Dim tpDictionary As Dictionary(Of String, Integer)
For Each productNumber As String In ProductNumbers
Using context As New SelmaEntities
Dim Table = (From GoodProducts In context.TestResults
Where (GoodProducts.Art_no = productNumber)
Select GoodProducts.Art_no, GoodProducts.Failed)
tpDictionary = (From FProducts In context.TestResults
Where (FProducts.Art_no = productNumber And FProducts.Failed <> 0)
Order By FProducts.Serial_number
Select FProducts.Serial_number, ).ToDictionary
End Using
Next
End Sub
ToDictionary requires lambda expressions as parameters: one to select the dictionary key, one to select the value. So try:
tpDictionary = (From FProducts In context.TestResults
Where (FProducts.Art_no = productNumber And FProducts.Failed <> 0))
.ToDictionary(Function(p) FProducts.Serial_number, Function(p) 0)
var products = from p in FProducts select new { value=serial_number,key=productid};
Dictionary<string, int> dictionary = new Dictionary<string, int>();
foreach(var item in products){
dictionary.Add(item.value, item.key);
}

loop through datatable to create a string that looks like this

I want to loop through my datatable column called SDESCR and created a string that looks like this.
Dim labels As String() = {"North", "South", "East", "West", "Up", "Down"}
this is what i am trying and it is not working
Dim labels As String()
For Each row As DataRow In tablegraph.Rows
labels = labels " ' " + row.Item("SDESCR") + " ',"
Next row
THANK YOU FOR THE HELP, I WILL TEST THEM TOMORROW AND SEE WHICH WORKS BEST AND MARK ONE CORRECT.
Do this instead
Dim labels As String()
Dim labelsList As List(Of String) = New List(Of String)
For Each row As DataRow In tablegraph.Rows
labelsList.Add(row.Item("SDESCR"))
Next
labels = labelsList.ToArray()
If you need it to be a comma delimited list instead you can just do
Dim commaLabels As String = String.Join(labels, ",")
If you need them stored in an array, then you can add them to a list and then call the ToArray() method on the list:
Dim labelList As New List(Of String)
For Each row As DataRow In tablegraph.Rows
labelList.Add(row.Item("SDESCR"))
Next row
Dim labels As String() = labelList.ToArray()
If you want a string, use this (string builder is best due to memory management issues with constant string declaration.
Dim labels As New StringBuilder()
For Each row As DataRow In tablegraph.Rows
labels.Append(" ' " + row.Item("SDESCR") + " ',")
Next row
Then when you need the string, use labels.ToString()
If you want an array, use this...
Dim labels As New List(Of String)()
For Each row As DataRow In tablegraph.Rows
labels.Add(row.Item("SDESCR"))
Next row
Then when you need the array, use labels.ToArray()
The main reason your above code is failing is that you are declaring an Array of strings.
If you mean a String-Array instead of a String, this works:
Dim labels(tablegraph.Rows.Count - 1) As String
For i As Int32 = 0 To tablegraph.Rows.Count - 1
labels(i) = tablegraph(i)("SDESCR").ToString
Next
If you want them separated with a comma, you can use a StringBuilder to append:
Dim labels As New System.Text.StringBuilder
For i As Int32 = 0 To tablegraph.Rows.Count - 1
labels.Append(" ' ").Append(tablegraph(i)("SDESCR").ToString).Append(" ',")
Next
If labels.Length <> 0 Then labels.Length -= 1 'remove last comma'
Dim labelString As String = labels.ToString
There are plenty of ways to do this; here is an approach using LINQ
Dim labels As String() = (From myRow In tablegraph _
Select CType(myRow.Item("SDESCR"), String)).ToArray
It's worth nothing that this will fail for NULL/NOTHING values of "SDESCR".
If you just want a single comma-separated values you can do this:
Dim sOutput = String.Join(",", (From myRow In tablegraph _
Select CType(myRow.Item("SDESCR"), String)).ToArray)
labels = labels " ' " + row.Item("SDESCR") + " ',"
^
Plus sign missing?
Also, when you do this you'll be left with an extra , at the end of your string. So you'll want to strip that off.

Retrieving auto-incremented column value in ASP.NET from mySQL table WITHOUT using stored proceedure

I a function that used a mySQL Data Adapter and inserts a new row.
I want the function to return the value of the auto-incremented column of the updated row.
Please help.
Public Function addRow(ByVal colA as String, ByVal colB as String) As Integer
Dim dbConnection As New MySqlConnection("server=xxx; user id=xxx; password=xxx; database=xxx; pooling=false;")
Dim dbDataAdapter As New MySqlDataAdapter("SELECT * FROM table", dbConnection)
Dim dbDataSet As DataSet = New DataSet
dbDataAdapter.Fill(dbDataSet, "table")
Dim dbNewRow As DataRow = dbDataSet.Tables("table").NewRow
dbNewRow("colA") = colA
dbNewRow("colB") = colB
dbDataSet.Tables("table").Rows.Add(dbNewRow)
dbDataAdapter.InsertCommand = New MySqlCommand("INSERT into table(colA, colB) VALUES (#colA, #colB)", dbConnection)
dbDataAdapter.InsertCommand.Parameters.Add("colA", MySqlDbType.VarChar, 256, "colA")
dbDataAdapter.InsertCommand.Parameters.Add("colB", MySqlDbType.VarChar, 256, "colB")
Dim dbParm As MySqlParameter = dbDataAdapter.InsertCommand.Parameters.Add("#colID", MySqlDbType.Int16, 16, "colID")
dbParm.Direction = ParameterDirection.ReturnValue
dbDataAdapter.Update(dbDataSet, "table")
Return dbDataAdapter.InsertCommand.Parameters("#colID").Value
End Function
The "Return..." line doesn't work and don't know what the correct code would be.
Assuming the insert stored procedure is doing something like
RETURN ##IDENTITY
You will need the equivalent of this:
oDatabase.AddParameter(oDbCommand, "#RETURN_VALUE", System.Data.DbType.Int32, System.Data.ParameterDirection.ReturnValue, "", System.Data.DataRowVersion.Current, null);
...
oDbCommand.ExecuteNonQuery();
returnStatusCode = (int)oDbCommand.Parameters[0].Value;
Try this:
Dim result As Integer = 0
Integer.TryParse(dbDataAdapter.InsertCommand.Parameters("#colID").Value, result)
Return result
I did it myself again.
Public Function addRow(ByVal colA as String, ByVal colB as String) As Integer
Dim dbConnection As New MySqlConnection("server=xxx; user id=xxx; password=xxx; database=xxx; pooling=false;")
Dim dbDataAdapter As New MySqlDataAdapter("SELECT * FROM table where colID = 0", dbConnection)
Dim dbDataSet As DataSet = New DataSet
dbDataAdapter.Fill(dbDataSet, "table")
Dim dbNewRow As DataRow = dbDataSet.Tables("table").NewRow
dbNewRow("colA") = colA
dbNewRow("colB") = colB
dbDataSet.Tables("table").Rows.Add(dbNewRow)
dbDataAdapter.InsertCommand = New MySqlCommand("INSERT into table(colA, colB) VALUES (#colA, #colB); Select * from table where colID = LAST_INSERT_ID()", dbConnection)
dbDataAdapter.InsertCommand.Parameters.Add("colA", MySqlDbType.VarChar, 256, "colA")
dbDataAdapter.InsertCommand.Parameters.Add("colB", MySqlDbType.VarChar, 256, "colB")
dbDataAdapter.Update(dbDataSet, "table")
Return dbDataSet.Tables("table").Rows(0).Item(0)
End Function
Seems all I needed to do was add a Select statement on the end of the Insert statement and use the LAST_INSERT_ID function to just get the last Inserted row. Then just read from that one rows ID and return it.
I am quite disappointed that DataAdapters work this way. I'm sure classic ASP was easier than this! Thanks to all who responded.

Resources