Get index for minimum value - vb.net

I'm trying to find the index of the minimum value inside an Array List in VB.net. I'll then use this index to split two array list at the same location.
I found the minimum value, but can't figure out how to get this value index.
Dim smallest As Double = Double.MaxValue
For Each element As Double In MyArray
smallest = Math.Min(smallest, element)
Next
Dim splitpoint = MyArray.IndexOf(smallest)
Console.WriteLine(smallest)
Console.WriteLine(splitpoint)
I get a result of -1 for split point which is not right. I'm sure this isn't the most efficient way to find the min value using with a loop.
Any help would me massive.
Thanks

Related

Refined list sorting by substring integer after alphabetical sorting

I have some information in a list (called listLines). Each line below is in a List(Of String).
1|This is just a header
3|This is just a footer
2|3456789|0000000|12312312313|BLUE|1|35.00
2|7891230|0000000|45645645655|BLUE|1|22.00
2|7891230|0000000|45645645658|RED|2|13.00
2|3456789|0000000|12312312316|RED|2|45.00
2|3456789|0000000|12312312317|YELLOW|5|-9.00
2|3456789|0000000|12312312315|ORANGE|3|15.00
2|7891230|0000000|45645645659|YELLOW|5|32.00
2|3456789|0000000|12312312314|GREEN|4|-20.00
2|7891230|0000000|45645645656|GREEN|4|39.00
2|7891230|0000000|45645645657|ORANGE|3|-18.50
I'm doing a listLines.sort() on the list to sort it alphabetically. Below is what I get after the .sort().
1|This is just a header
2|3456789|0000000|12312312313|BLUE|1|35.00
2|3456789|0000000|12312312314|GREEN|4|-20.00
2|3456789|0000000|12312312315|ORANGE|3|15.00
2|3456789|0000000|12312312316|RED|2|45.00
2|3456789|0000000|12312312317|YELLOW|5|-9.00
2|7891230|0000000|45645645655|BLUE|1|22.00
2|7891230|0000000|45645645656|GREEN|4|39.00
2|7891230|0000000|45645645657|ORANGE|3|-18.50
2|7891230|0000000|45645645658|RED|2|13.00
2|7891230|0000000|45645645659|YELLOW|5|32.00
3|This is just a footer
With that said, I need to output this information to a file. I'm able to do this ok. I still have a problem though. There is a sequence number in the above data at position 5 just after the listed colors (RED, BLUE, ETC..) that you can see. It's just before the last value which is a decimal type.
I need to further sort this list, keeping it in alphabetical order since position 2 is an account number and I want to keep the account numbers grouped together. I just want them to be resorted in sequential order based on the sequence number.
I was looking at another thread trying to figure out how I can do this. I found a piece of code like listLines.OrderBy(Function(q) q.Substring(35)).ToArray. I think this would probably help me if this was a fixed length file, it isn't however. I was thinking I can do some kind of .split() to get the 5th piece of information and sort it but then it's going to unalphabetize and mix the lines back up because I don't know how to specify to still keep it alphabetical.
Right now I'm outputting my alphabetical list like below so I can format it with commas and double quotes.
For Each listLine As String In listLines
strPosition = Split(listLine, "|")
Dim i As Integer = 1
Dim iBound As Integer = UBound(strPosition)
Do While (i <= iBound)
strOutputText = strOutputText & Chr(34) & strPosition(i) & Chr(34) & ","
i += 1
Loop
My main question is how do I re-sort after .sort() to then get each account (position1) in sequential order (position 5)? OR EVEN BETTER, how can I do both at the same time?
The List(Of T) class has an overload of the Sort method that takes a Comparison(Of T) delegate. I would suggest that you use that. It allows you to write a method or lambda expression that will take two items and compare them any way you want. In this case, you could do that like this:
Dim items = New List(Of String) From {"1|This Is just a header",
"3|This Is just a footer",
"2|3456789|0000000|12312312313|BLUE|1|35.00",
"2|7891230|0000000|45645645655|BLUE|1|22.00",
"2|7891230|0000000|45645645658|RED|2|13.00",
"2|3456789|0000000|12312312316|RED|2|45.00",
"2|3456789|0000000|12312312317|YELLOW|5|-9.00",
"2|3456789|0000000|12312312315|ORANGE|3|15.00",
"2|7891230|0000000|45645645659|YELLOW|5|32.00",
"2|3456789|0000000|12312312314|GREEN|4|-20.00",
"2|7891230|0000000|45645645656|GREEN|4|39.00",
"2|7891230|0000000|45645645657|ORANGE|3|-18.50"}
items.Sort(Function(x, y)
Dim xParts = x.Split("|"c)
Dim yParts = y.Split("|"c)
'Compare by the first column first.
Dim result = xParts(0).CompareTo(yParts(0))
If result = 0 Then
'Compare by the second column next.
result = xParts(1).CompareTo(yParts(1))
End If
If result = 0 Then
'Compare by the sixth column last.
result = xParts(5).CompareTo(yParts(5))
End If
Return result
End Function)
For Each item In items
Console.WriteLine(item)
Next
If you prefer a named method then do this:
Private Function CompareItems(x As String, y As String) As Integer
Dim xParts = x.Split("|"c)
Dim yParts = y.Split("|"c)
'Compare by the first column first.
Dim result = xParts(0).CompareTo(yParts(0))
If result = 0 Then
'Compare by the second column next.
result = xParts(1).CompareTo(yParts(1))
End If
If result = 0 Then
'Compare by the sixth column last.
result = xParts(5).CompareTo(yParts(5))
End If
Return result
End Function
and this:
items.Sort(AddressOf CompareItems)
Just note that this is rather inefficient because it splits both items on each comparison. That's not a big deal for a small list but, if there were a lot of items, it would be better to split each item once and then sort based on those results.

How to get index with known value as string in arraylist?

I have ArrayList with multi dimensional values in Structure as ArrayList
Structure
(0)=> Mstructure.ABCD
Area (these are value of ABCD)
Name
(1)=> Mstructure.EFGH
Area
Name
I want to know the index of string ABCD.
I tried
Dim myIndex as Integer = Structure.IndexOf("ABCD")
Dim myIndex = Array.IndexOf(Structure.ToArray(), myString)
This returned only -1. I want to get 0 if string is ABCD
EDITED
Structure is defined as ArrayList. I can iterate over it if I use loop e.g
Structure(i).GetType().Name = "ABCD"
I have checked if it exists in the ArrayList
Dim result = Structure.ToArray().Any(Function(x) x.ToString().Contains("ABCD"))
But I want to know the index of the multidimensional ArrayList without looping it. I want to get the index of Mstructure.ABCD. Msttructure.ABCD has values inside it but without knowing those values I want to get the index value.
(0){Mstructure.ABCD}
(1){Mstructure.EFGH}
(2){Mstructure.IJKL}
hhmmm i would use collections instead, or create an object with multi collections to make it easier for me... Have you thought of that?

Finding lowest value in List of tuple in VB.Net

I am trying to find lowest Item2 and return Item1 from tuple list, I tried to do it with List.Min but I couldn't get it right, here is my code.
Dim ahlist As New List(Of Tuple(Of String, Double))
ahlist.Add(Tuple.Create("test1", 1.2))
ahlist.Add(Tuple.Create("test2", 0.2))
ahlist.Add(Tuple.Create("test3", 1.8))
Basically I want to find lowest number and return string (test2) in this case.
I'd recommend using a different data structure for this:
https://msdn.microsoft.com/en-us/library/ms132329(v=vs.110).aspx
You add the key/value combinations. The 0th one in the list is always the minimum key, making its an O(1) operation instead of O(n). In this case, the key would be the Decimal, and the value would be the string.
You can reverse the order of the items for the comparison to be by the number first:
Dim ahlist As New List(Of Tuple(Of Double, String))
ahlist.Add(Tuple.Create(1.2, "test1"))
Just a simple fix from C# syntax to VB.net to #Aamir Nakehwa's answer.
Dim minValue As Double = ahlist.Min(Function(x) x.Item2)
Debug.Print(minValue.ToString)
ahlist.Min(x => x.Item2)
Try this. I will return you the minimum value from your tuple list.
And hold it in any variable to use like below
Dim minValue as Double = ahlist.Min(Function(x) x.Item2)

Array of Integers Comparing Integers VB.NET

Basically I have and array of integers that vary in size. I need to compare each number to each other number and display which number is repeated. For example:
Dim ints() As Integer = {1,2,2,5,4,6}
The number that shows up more than once is 2.
How can I run through the array and compare each integer with the numbers in the array. I tried a for loop but it didn't return the value I was looking for. I am new to VB.NET and do not understand fully.
Dim ints() As Integer = {1,2,2,5,4,6}
Dim repeatedNumbers = ints.GroupBy(Function(intValue) intValue) _
.Where(Function(grp) grp.Count > 1)
For each grp in repeatedNumbers
Console.WriteLine("Number {0} is repeated {1} times", grp(0), grp.Count)
Next
What this code does:
We first call GroupBy, which groups items by their value. The Function gets the grouping key, in this case we simply group by the array's value itself. This call returns a sequence of
groups. There is one group for every unique value in the array. The
group contains all items that correspond to a unique value. So if a value appears twice in the array, there will be a group which contains two ints with this value.
We call Where to filter groups. We only want groups for which the count is greater than one, so that only duplicate values are considered.
We then loop through the result. grp(0) gives us the first number in the group (we could have picked any number in the group, since all numbers in a group are the same!) and the Count property gives us the number of repetitions.
I would try it with something like this:
Dim ints() As Integer = {1, 2, 2, 5, 4, 6}
Array.Sort(ints)
For i = 1 To ints.GetUpperBound(0)
If ints(i) = ints(i - 1) Then MessageBox.Show(String.Format("{0} is repeated", ints(i)))
Next
Doing it like this on a sorted array keeps down the nesting.
I've not tested this but it should be along the right lines.
You could use LINQ to find the duplicates:
Dim repeating = (From n In ints
Group By n Into Dups = Group
Where Dups.Count > 1
Select Dups.First).ToArray()
This returns an Array of integers which only contains numbers that are not unique in the original array.
So this displays the repeating number(s):
MessageBox.Show(String.Format("Duplicates found: {0}", String.Join(","c, repeating)))

Pick a random number from a set of numbers

I have an array of integers like these;
dim x as integer()={10,9,4,7,6,8,3}.
Now I want to pick a random number from it,how can I do this in visual basic?Thanks in advance...
First you need a random generator:
Dim rnd As New Random()
Then you pick a random number that represents an index into the array:
Dim index As Integer = rnd.Next(0, x.Length)
Then you get the value from the array:
Dim value As Integer = x(index)
Or the two last as a single statement:
Dim value As Integer = x(rnd.Next(0, x.Length))
Now, if you also want to remove the number that you picked from the array, you shouldn't use an array in the first place. You should use a List(Of Integer) as that is designed to be dynamic in size.
randomly choose an index from 0 to length-1 from your array.