Assign an integer variable to an integer variable and change name dynamic - vb.net

Dim LastNumber as Integer = 1
Dim num_0() as Integer = {1, 2, 3, 4, 5}
Dim num_1() as Integer = {6, 7, 8, 9, 10}
Dim num_2() as Integer = {20, 21, 14, 36, 0}
Dim y() As Integer
y(0) = num_0(2)
When I use this code it executes perfectly
But the problem is I want to change the "0" in num_0(2)
When I do...
y(0) = num_ & LastNumber & (2)
This doesnt work
Or
y(0) = ("num_" & LastNumber & "(2)")
This gives me an error that converting a string to an integer is not possible
My question is How can I replace the "0" in num_0(2) with the LastNumber integer variable... so it reads the "8" out of the array num_1(2)

You can use multidimensional array (AKA rectangular array):
Dim num As Integer(,) = { {1, 2, 3, 4, 5}, {6, 7, 8, 9, 10}, {20, 21, 14, 36, 0} }
y(0) = num(LastNumber, 2)
or jagged array (array of arrays) :
Dim num As Integer()() = { ({1, 2, 3, 4, 5}), ({6, 7, 8, 9, 10}), ({20, 21, 14, 36, 0}) }
y(0) = num(LastNumber)(2)

Related

Rank numbers in a loop vb.net

I currently pull data from a database and rank them when i loop through them. Example of such numbers are 45, 45, 67, 99, 34, 65, 88, 22, 90, 90, 90, 23, 55, 46. These are a total of 14 numbers, I want to loop through and assign rank.
Dim i As Integer() = {45, 45, 67, 99, 34, 65, 88, 22, 90, 90, 90, 23, 55, 46}
Dim lastScore As Integer
Dim position As Integer = 0
For Each i1 In i
If Val(lastScore) <> Val(i1) Then
position += 1
Console.WriteLine(position & vbCrLf)
ElseIf Val(lastScore) = Val(i1) Then
Console.WriteLine(position & vbCrLf)
position += 1
End If
lastScore = Val(i1)
Next
The current output of the code above is:
1, 1, 3, 4, 5, 6, 7, 8, 9, 9, 10, 12, 13, 14
Which is wrong. The expected output is supposed to be:
1, 1, 3, 4, 5, 6, 7, 8, 9, 9, 9, 12, 13, 14
How can I achieve this?
Here is an ugly code which creates the expected output:
Dim i As Integer() = {45, 45, 67, 99, 34, 65, 88, 22, 90, 90, 90, 23, 55, 46}
Dim lastScore As Integer
Dim lastScorePosition As Integer
Dim position As Integer = 1
For Each i1 In i
If Val(lastScore) <> Val(i1) Then
Console.Write(position & ",")
lastScorePosition = position
lastScore = Val(i1)
Else
Console.Write(lastScorePosition & ",")
End If
position += 1
Next
The expected result is not correct. I.e. why there is not rank 2?
Simple ranking is achieved with relatively simple code:
Sub Main()
Dim i As Integer() = {45, 45, 67, 99, 34, 65, 88, 22, 90, 90, 90, 23, 55, 46}
Dim lastScore As Integer
Dim position As Integer
Dim sb As New StringBuilder
For Each i1 In i
If Not lastScore = i1 Then position += 1
sb.Append(position & ", ")
lastScore = i1
Next
sb.Remove(sb.Length - 2, 2)
Console.WriteLine(sb.ToString)
Console.ReadLine()
End Sub
The output is:
1, 1, 2, 3, 4, 5, 6, 7, 8, 8, 8, 9, 10, 11

how to do vb.net replace on a byte array

I have a byte array of data. How can I find and replacement a part of the byte array with replacement data?
dim foo as byte
foo = MY DATA
If foo was a string, then I would do:
foo = replace( foo, target, replacement )
But foo is a byte array. How can I replace?
Just for the fun of it, here is an implementation:
<TestMethod()>
Public Sub Test_ArrayReplace()
AssertEqualArray({1, 4}, ArrayReplace({1, 2, 3}, {2, 3}, {4}))
AssertEqualArray({1, 4, 5}, ArrayReplace({1, 2, 3, 5}, {2, 3}, {4}))
AssertEqualArray({1, 4, 2}, ArrayReplace({1, 2, 3, 2}, {2, 3}, {4}))
AssertEqualArray({1, 4, 5, 2}, ArrayReplace({1, 2, 3, 2}, {2, 3}, {4, 5}))
AssertEqualArray({1, 2, 3, 8, 9}, ArrayReplace({1, 2, 3, 8, 2, 3, 4}, {2, 3, 4}, {9}))
AssertEqualArray({1, 68, 69, 70, 255}, ArrayReplace({1, 65, 66, 67, 255}, "ABC", "DEF", Encoding.ASCII))
End Sub
Private Sub AssertEqualArray(expected() As Byte, actual() As Byte)
Assert.IsNotNull(expected, "expected")
Assert.IsNotNull(actual, "actual")
Assert.AreEqual(expected.Length, actual.Length, "length")
For index = 0 To actual.Length - 1
Assert.AreEqual(expected(index), actual(index), String.Format("index: {0}", index))
Next
End Sub
Public Function ArrayReplace(data() As Byte, find As String, replacement As String, enc As Encoding) As Byte()
Return ArrayReplace(data, enc.GetBytes(find), enc.GetBytes(replacement))
End Function
Public Function ArrayReplace(data() As Byte, find() As Byte, replacement() As Byte) As Byte()
Dim matchStart As Integer = -1
Dim matchLength As Integer = 0
Using mem = New IO.MemoryStream
For index = 0 To data.Length - 1
If data(index) = find(matchLength) Then
If matchLength = 0 Then matchStart = index
matchLength += 1
If matchLength = find.Length Then
mem.Write(replacement, 0, replacement.Length)
matchLength = 0
End If
Else
If matchLength > 0 Then
mem.Write(data, matchStart, matchLength)
matchLength = 0
End If
mem.WriteByte(data(index))
End If
Next
If matchLength > 0 Then
mem.Write(data, data.Length - matchLength, matchLength)
End If
Dim retVal(mem.Length - 1) As Byte
mem.Position = 0
mem.Read(retVal, 0, retVal.Length)
Return retVal
End Using
End Function
The implementation is surely not perfect and might even be buggy.
Keep in mind that in order to convert a String into an ByteArray you have to know the Encoding of the String.
You can call it this way:
foo = ArrayReplace(foo, "find", "replace", Encoding.UTF8)

VB.NET - How to calculate the parity bit of a byte array

What is the most efficient way calculate the parity bit (if the number of active bits are odd or even) in a byte array? I have though about iterating through all the bits and summing up the active bits, but that would be very impractical purely based on the number of iterations required on larger byte arrays/files.
For your convenience (and my curiosity), I have done some timing tests with a parity lookup table compared to the other two methods suggested so far:
Module Module1
Dim rand As New Random
Dim parityLookup(255) As Integer
Sub SetUpParityLookup()
' setBitsCount data from http://stackoverflow.com/questions/109023/how-to-count-the-number-of-set-bits-in-a-32-bit-integer
Dim setBitsCount = {
0, 1, 1, 2, 1, 2, 2, 3, 1, 2, 2, 3, 2, 3, 3, 4,
1, 2, 2, 3, 2, 3, 3, 4, 2, 3, 3, 4, 3, 4, 4, 5,
1, 2, 2, 3, 2, 3, 3, 4, 2, 3, 3, 4, 3, 4, 4, 5,
2, 3, 3, 4, 3, 4, 4, 5, 3, 4, 4, 5, 4, 5, 5, 6,
1, 2, 2, 3, 2, 3, 3, 4, 2, 3, 3, 4, 3, 4, 4, 5,
2, 3, 3, 4, 3, 4, 4, 5, 3, 4, 4, 5, 4, 5, 5, 6,
2, 3, 3, 4, 3, 4, 4, 5, 3, 4, 4, 5, 4, 5, 5, 6,
3, 4, 4, 5, 4, 5, 5, 6, 4, 5, 5, 6, 5, 6, 6, 7,
1, 2, 2, 3, 2, 3, 3, 4, 2, 3, 3, 4, 3, 4, 4, 5,
2, 3, 3, 4, 3, 4, 4, 5, 3, 4, 4, 5, 4, 5, 5, 6,
2, 3, 3, 4, 3, 4, 4, 5, 3, 4, 4, 5, 4, 5, 5, 6,
3, 4, 4, 5, 4, 5, 5, 6, 4, 5, 5, 6, 5, 6, 6, 7,
2, 3, 3, 4, 3, 4, 4, 5, 3, 4, 4, 5, 4, 5, 5, 6,
3, 4, 4, 5, 4, 5, 5, 6, 4, 5, 5, 6, 5, 6, 6, 7,
3, 4, 4, 5, 4, 5, 5, 6, 4, 5, 5, 6, 5, 6, 6, 7,
4, 5, 5, 6, 5, 6, 6, 7, 5, 6, 6, 7, 6, 7, 7, 8
}
For i = 0 To 255
parityLookup(i) = setBitsCount(i) And 1
Next
End Sub
' Method using lookup table
Function ParityOfArray(a() As Byte) As Integer
Dim parity As Integer = 0 ' use an Integer because they are faster
For i = 0 To a.Length - 1
parity = parity Xor parityLookup(a(i))
Next
Return parity
End Function
' Method by Alireza
Function ComputeParity(bytes() As Byte) As Byte
Dim parity As Boolean = False
For i As Integer = 0 To bytes.Length - 1
Dim b As Byte = bytes(i)
While b <> 0
parity = Not parity
b = CByte(b And (b - 1))
End While
Next
Return Convert.ToByte(parity)
End Function
' Method by dbasnett
Function CountBits(byteArray As Byte()) As Integer
Dim rv As Integer = 0
For Each b As Byte In byteArray
Dim count As Integer = b
count = ((count >> 1) And &H55) + (count And &H55)
count = ((count >> 2) And &H33) + (count And &H33)
count = ((count >> 4) And &HF) + (count And &HF)
rv += count
Next
Return rv
End Function
Sub FillWithRandomBytes(ByRef a() As Byte)
rand.NextBytes(a)
End Sub
Sub Main()
SetUpParityLookup()
Dim nBytes = 10000
Dim a(nBytes - 1) As Byte
FillWithRandomBytes(a)
Dim p As Integer
Dim sw As New Stopwatch
sw.Start()
p = ParityOfArray(a)
sw.Stop()
Console.WriteLine("ParityOfArray - Parity: {0} Time: {1}", p, sw.ElapsedTicks)
sw.Restart()
p = ComputeParity(a)
sw.Stop()
Console.WriteLine("ComputeParity - Parity: {0} Time: {1}", p, sw.ElapsedTicks)
sw.Restart()
p = CountBits(a)
sw.Stop()
' Note that the value returned from CountBits should be And-ed with 1.
Console.WriteLine("CountBits - Parity: {0} Time: {1}", p And 1, sw.ElapsedTicks)
Console.ReadLine()
End Sub
End Module
Typical ouput:
ParityOfArray - Parity: 0 Time: 386
ComputeParity - Parity: 0 Time: 1014
CountBits - Parity: 0 Time: 695
An efficient way to do this is to use the x & (x - 1) operation in a loop, until x becomes zero. This way you will loop only by the number of bits set to 1.
In VB.NET for a byte array:
Function ComputeParity(bytes() As Byte) As Byte
Dim parity As Boolean = False
For i As Integer = 0 To bytes.Length - 1
Dim b As Byte = bytes(i)
While b <> 0
parity = Not parity
b = b And (b - 1)
End While
Next
Return Convert.ToByte(parity)
End Function
Here is a function that counts bits.
Private Function CountBits(byteArray As Byte()) As Integer
Dim rv As Integer = 0
For x As Integer = 0 To byteArray.Length - 1
Dim b As Byte = byteArray(x)
Dim count As Integer = b
count = ((count >> 1) And &H55) + (count And &H55)
count = ((count >> 2) And &H33) + (count And &H33)
count = ((count >> 4) And &HF) + (count And &HF)
rv += count
Next
Return rv
End Function
Note: this code came from a collection of bit twiddling hacks I found some years ago. I converted it to VB.

String to double array

I need to take this string:
Dim tmpTry As String = "10, 20, 30, 40, 50, 52, 20, 20, 10, 35, 3, 8, 47, 7, 2, 5, 55, 8, 0, 0, 6, 55, 0, 2, 12, 0, 0, 21, 14, 0, 3"
And convert it to a double array:
Dim arrNumOfVisits As Double() = New Double(tmpTry) {}
How do i go about doing that?
FYI the arrNumOfVisits goes into a ParamArray System.Collections.IEnumerable()
David
Dim arrString As String() = tmpTry.Split(New Char() {" "C})
Dim arrNumOfVisits As Double() = New Double(arrString.Length) {}
Dim i As Integer = 0
While i < arrString.Length
arrNumOfVisits(i) = Double.Parse(arrString(i))
i += 1
End While
The above code will do the trick, using regEx on this would be overkill.
Never the less do try to learn the basic RegEx operations, here are my favorite cheat sheets:
http://regexlib.com/CheatSheet.aspx?AspxAutoDetectCookieSupport=1
http://www.cheatography.com/davechild/cheat-sheets/regular-expressions/

How to set an array to a list of values in VB.NET?

I cannot figure out how to set an array to one of two sets of numbers (there will be more later), every way that I have tried throws some kind of error. I have tried to Dim the array inside the case statements, but then I cannot use the array in the For Each, which makes this worthless.... any ideas would be appreciated.
Code:
Dim HourArray() As Integer
Select Case CurrentShapeRow(ROW_PERIOD)
Case "ON", "2X16"
HourArray = {6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21}
Case "2X8", "5X8"
HourArray = {0, 1, 2, 3, 4, 5, 22, 23}
Case Else
Throw New Exception(String.Format("Unhandled Period: {0}", CurrentShapeRow(ROW_PERIOD)))
End Select
For Each HourCount As Integer In HourArray()
'DO SOME STUFF HERE
Next
HourArray = New Integer() {1,2,3,4,5,6,7,8,9}
When you assign an array to an existing variable you must use a constructor explicitly:
HourArray = New Integer() { 6, 7, 8, 9, 10, 11, 12, 13 }
This differs from a declaration and assignment where the constructor is optional:
Dim HourArray() As Integer = { 6, 7, 8, 9, 10, 11, 12, 13 }
Dim hourArray As List(Of Integer)
Select Case CurrentShapeRow(ROW_PERIOD)
Case "ON", "2X16"
hourArray.AddRange(New Integer() {6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21})
Case "2X8", "5X8"
hourArray.AddRange(New Integer() {0, 1, 2, 3, 4, 5, 22, 23})
Case Else
Throw New Exception(String.Format("Unhandled Period: {0}", CurrentShapeRow(ROW_PERIOD)))
End Select
For Each i As Integer In hourArray
Console.WriteLine(i)
Next