i have this code, and i want to access some variables.
Dim k1 as String = "Something"
Dim k2 as String = "Something"
... to k230
------------------Then i have this:
Dim rnd = New Random()
Dim nextValue = rnd.Next(230)
For i = 0 To 230
If nextValue = i Then
MsgBox('k+i') <--BUT READ THIS AS A VARIABLE.
End If
i = i + 1
Next
i readed some similar questions, but them doesn't apply to this case.
Consider using arrays here:
http://msdn.microsoft.com/en-us/library/vstudio/wak0wfyt.aspx
An array is a set of values that are logically related to each other,
such as the number of students in each grade in a grammar school.
By using an array, you can refer to these related values by the same
name, and use a number that’s called an index or subscript to tell
them apart. The individual values are called the elements of the
array. They’re contiguous from index 0 through the highest index
value.
Try using a Dictionary:
Dim k As New Dictionary(Of Integer, String)()
k.Add(1, "Something")
k.Add(2, "Something")
'... to 230
Messagebox.Show(k(i))
Related
I have a DataTable dtand need to store the first n items of a certain column in an integer array. I know it's easy to do this with a loop like this:
Dim array(n-1) As Integer
For i As Integer = 0 To n-1
array(i) = dt.Rows(i).Item("columName")
Next
Nonetheless, is there a more convenient way to store these items in the array?
"Without using a loop" is impossible since there is no magic way to retrieve items from a collection without looping it. However, maybe you think that LINQ does not use loops:
Dim columNameValues = From row In dt
Select row.Field(Of Int32)("columName")
Dim array As Int32() = columNameValues.ToArray()
Gets all values from all rows, if you want to get n values use Enumerable.Take:
Dim array As Int32() = columNameValues.Take(n).ToArray()
In VB.NET you can even use Take in a LINQ query:
Dim first10Values = From row In dt
Select row.Field(Of Int32)("columName")
Take 10
For what it's worth, as Barry has mentioned it is technically possible to get n items from a collection without using a loop, but see yourself:
Dim value1 As Int32 = dt.Rows(0).Field(Of Int32)("columName")
Dim value2 As Int32 = dt.Rows(1).Field(Of Int32)("columName")
Dim value3 As Int32 = dt.Rows(2).Field(Of Int32)("columName")
' ..... '
Dim value10 As Int32 = dt.Rows(9).Field(Of Int32)("columName")
You could add them to a List(Of Int32), but that's just for demonstration purposes anyway.
How can I select any random string from a given list of strings? Example:
List1: banana, apple, pineapple, mango, dragon-fruit
List2: 10.2.0.212, 10.4.0.221, 10.2.0.223
When I call some function like randomize(List1) = somevar then it will just take any string from that particular list. The result in somevar will be totally random. How can it be done? Thank you very much :)
Use Random
Dim rnd = new Random()
Dim randomFruit = List1(rnd.Next(0, List1.Count))
Note that you have to reuse the random instance if you want to execute this code in a loop. Otherwise the values would be repeating since random is initialized with the current timestamp.
So this works:
Dim rnd = new Random()
For i As Int32 = 1 To 10
Dim randomFruit = List1(rnd.Next(0, List1.Count))
Console.WriteLine(randomFruit)
Next
since always the same random instance is used.
But this won't work:
For i As Int32 = 1 To 10
Dim rnd = new Random()
Dim randomFruit = List1(rnd.Next(0, List1.Count))
Console.WriteLine(randomFruit)
Next
Create a List of Strings.
Create a random number generator: Random class
Call Random number generator's NextInt() method with List.Count as the upper bound.
Return List[NextInt(List.count)].
Job done :)
Generate a random number between 1 and the size of the list, and use that as an index?
Try this:
Public Function randomize(ByVal lst As ICollection) As Object
Dim rdm As New Random()
Dim auxLst As New List(Of Object)(lst)
Return auxLst(rdm.Next(0, lst.Count))
End Function
Or just for string lists:
Public Function randomize(ByVal lst As ICollection(Of String)) As String
Dim rdm As New Random()
Dim auxLst As New List(Of String)(lst)
Return auxLst(rdm.Next(0, lst.Count))
End Function
You could try this, this is a simple loop to pick every item from a list, but in a random manner:
Dim Rand As New Random
For C = 0 to LIST.Count - 1 'Replace LIST with the collection name
Dim RandomItem As STRING = LIST(Rand.Next(0, LIST.Count - 1)) 'Change the item type if needed (STRING)
'' YOUR CODE HERE TO USE THE VARIABLE NewItem ''
Next
I want to get value from datatable and then store it to the string() arraylist. datatable contain 3 column (columnA | columnB | columnC). I want to get all value from columnB and store it to arraylist.
I have try something like this
If myTableData.Rows.Count > 0 Then
For i As Integer = 0 To myTableData.Rows.Count - 1
Dim value() As String = myTableData.Rows(i)(1)
Next
End If
but when I compile that code, I got error message like this :
Unable to cast object of type 'System.String' to type 'System.String[]'
please help me.....
You could do that with LINQ:
Dim colBValues = (From row In myTableData Select colB = row(1).ToString).ToList
Or if you prefer the "old-school" way:
Dim colBValues = New List(Of String)
For Each row As DataRow In myTableData.Rows
colBValues.Add(row(1).ToString)
Next
I've used a List(Of String) because it's type-safe, therefore you don't need to cast the values everytime. That makes code more readable, more failsafe and faster.
If you need it as String-Array, you could simply use ToArray:
Dim colBValues = (From row In myTableData Select colB = row(1).ToString).ToArray
List(T)
LINQ
Dim a() As String
Dim total As Integer
'Count the number of rows
total = myTableData.Rows.Count - 1
ReDim a(0 To total)
For i = 0 To total
a(i) = myTableData.Rows(i)(1)
Next
This is really old question, but I'll provide one more variant of answer :
Dim value = myTableData.Rows.OfType(Of DataRow).Select(Function(x) x(1).ToString()).ToArray
So, if You have more than one column in Your DataTable You can use x(columnIndex) instead 1.
I have this project that let user inputs 5 different numbers from 1 to 50. But I want to validate it before saving to DB that i will be 5 unique numbers. What's the best and fastest way to do this?
You can use HashSet(Of T) to check this:
Dim numbers As IEnumerable(Of Integer) = GetInputFromUser()
Dim hash As HashSet(Of Integer) = new HashSet(Of Integer)(numbers)
Dim unique As Boolean = hash.Count = numbers.Count()
This will be much more efficient than options requiring a sort + iteration.
Check this code
Private Function HasDuplicates(ByVal arr As Array) As Boolean
For i As Integer = 0 To arr.Length - 1
If Not arr(i) Is Nothing Then
Dim l As Integer = Array.LastIndexOf(arr, arr(i))
If l <> i Then Return True
End If
Next
Return False
End Function
Reed Copsey's suggestion to use hash sets was a good one (I hadn't worked with the HashSet class before).
But I then discovered that the IEnumerable class offers an extension method called Distinct that copies the unique values from a source IEnumerable to a target IEnumerable.
Borrowing the first line of Reed's sample code, here's the new sample VB.NET code:
Dim numbers As IEnumerable(Of Integer) = GetInputFromUser()
Dim isUnique As Boolean = (numbers.Distinct.Count = numbers.Count)
The variable isUnique is True if the numbers IEnumerable contains no duplicate values, or False if it contains one or more duplicate values.
Put in an array, sort it and check if elements 1,2 2,3 3,4 and 4,5 are different (in a loop).
Pseudocode:
integer numbers[50]
zeroarray(numbers, 50)
integer count = 0;
while (count < 5)
{
integer value = getinput()
if (value >= 1 and value <= 50)
if (numbers[value] = 0)
{
count = count + 1
numbers[value] = 1
}
else
reject duplicate
else
reject invalid
}
You can try this very simple method:
Filtering Arrays using LINQ
To simplifiy lets say the user inputs 5 different numbers from 0 to 49.
You can create a Boolean Array IsUsed(49) with 50 elements.
Then when the user input the value iInputNum=30 you can set IsUsed(30)=TRUE.
Next time, when the user input the second value iInputNum=7, you can set IsUsed(7)=TRUE
In this way you can check in a very fast way if the number was already inserted.
if IsUsed(iInputNum) then
'Skip the Input (put the right code here)
else
'Accept the number
IsUsed(iInputNum)=TRUE
'save iInputNum in the database
end if
Do not forget to clear the array after inserting all 5 numbers.
Remenber to put the right index in order to handle the number 1-50 (e not 0-49)
Here's an alternate solution, not sure how it compares, efficiency wise, to the other solutions, but it seems to work (uses LINQ).
Dim numbers As List<int> = getListOfNumbers()
Dim allUnique As Boolean = numbers.Distinct().Count() = numbers.Count()
Very late to the party, but what about something like this (C#, sorry)?
byte[] hits = new byte[51];
byte[] entries = new byte[] { 1, 12, 12, 32, 26, 49 };
foreach (var entry in entries)
{
hits[entry]++;
}
The elements in the hits array are automatically initialized to 0. When the foreach loop is complete, hits will contain the occurrence count for every number in entries. If any is greater than 1, you have dupes.
I am trying to make an array of hashtables. I don't know if this is the best solution, in PHP I would just do a multi-dim array, but it's not so easy in .NET. I am pretty new o VB, so if there is a better solution for this please explain.
I have 2 emails fields for a contact, and a contact can have many. I just want to load in the first two on the edit page for editing, whatever they may be.
Private Sub loadPrimaryContactEmails(ByVal db As CRMDataDataContext, ByVal contactID As Guid)
Dim q = (From ce In db.ContactEmails Where ce.ContactID = contactID Select ce).Take(2)
Dim Emails As Array
Dim count = 0
For Each email In q
Emails(count) = New Hashtable
Emails(count).Add("email", email.Email)
Emails(count).Add("label", email.Label)
Emails(count).Add("id", email.ContactEmailID)
count = count + 1
Next
txtPCEmail1.Text = Emails(0).Item("email")
txtPCEmail1Label.Text = Emails(0).Item("label")
lblEmail1ID.Text = Emails(0).Item("id")
txtPCEmail2.Text = Emails(1).Item("email")
txtPCEmail2Label.Text = Emails(1).Item("label")
lblEmail2ID.Text = Emails(1).Item("id")
End Sub
I get the error the first time I try to reference my array:
txtPCEmail1.Text = Emails(0).Item("email")
The error is:
Object variable or With block variable not set.
It builds, so I thought it might work. I can't just loop through my datasource because I have to explicitly set textbox fields. Is there a better way to go about doing this? Or is there a way to make an array of hashtables work?
EDIT - here is the good code:
So I went w/ the HybridDictionary...
Private Sub loadPrimaryContactEmails(ByVal db As CRMDataDataContext, ByVal contactID As Guid)
Dim q = (From ce In db.ContactEmails Where ce.ContactID = contactID Select ce).Take(2)
Dim Emails As New HybridDictionary()
Dim count = 1
For Each email In q
Emails.Add("email" + NCStr(count), email.Email)
Emails.Add("label" + NCStr(count), email.Label)
Emails.Add("id" + NCStr(count), email.ContactEmailID)
count = count + 1
Next
txtPCEmail1.Text = Emails("email1")
txtPCEmail1Label.Text = Emails("label1")
lblEmail1ID.Text = Emails("id1")
txtPCEmail2.Text = Emails("email2")
txtPCEmail2Label.Text = Emails("label2")
lblEmail2ID.Text = Emails("id2")
End Sub
SO yeah, kind of a hack, but I don't feel like I should have to making special methods just to load some data into a dictionary or array or whatever.
Arrays in VB.NET are different than in PHP. You will need to define the size of your array before attempting to set elements of the array.
Better yet, consider using the generic List<T> collection.
Yes Phil is right you haven't specified the Initial Size of the Array.
And as suggested by him Use generic list or I would recommend
"System.Collections.Specialized.StringCollection" Class or "System.Collections.Specialized.HybridDictionary" class
Build the hashtable first and then build the array.
Dim hash As New Hashtable()
hash.Add("Header", shortModel)
hash.Add("SpecInfo", specinfo)
hash.Add("SerialNumber", serie & "-L")
hash.Add("SerialNumber2", serie)
hash.Add("seriel", serie & "-L")
hash.Add("serie", serie)
hash.Add("Product", modelBase)
hash.Add("varBC", bc)
hash.Add("box_id", boxId.Substring(4).ToString)
Dim dt As DataTable = DbUtil.GetCursor("SFISM4.PKG_AGENCY.sp_get_print_param", {New OracleParameter("in_serie", "3CE5151ZW4")})
For Each row As DataRow In dt.Rows
hash.Add(row("NAME"), row("VALUE"))
Next
Dim mArray(hash.Count() - 1, 1) As String
Dim i As Integer = 0
For Each row As DictionaryEntry In hash
mArray(i, 0) = row.Key.ToString()
mArray(i, 1) = row.Value.ToString()
i = i + 1
Next