VB.NET Get Keys by sorted Values in Hashtable - arrays

I am studying VB.NET and I want to know better idea to get Keys by sorted values in Hashtable
Here is my solution that I built
Dim int_Value As Integer() = New Integer() {-9, 2, 8, 6, 8, 1, -9}
Dim int_Key As Integer() = New Integer() {1, 2, 3, 4, 5, 6, 7}
Dim Dum_Int(int_Key.Length) As Integer
Dim STORE_KEYS As New ArrayList
Array.Copy(int_Value, Dum_Int, Dum_Int.Length - 1)
Array.Sort(Dum_Int)
Array.Reverse(Dum_Int)
For I = 0 To Dum_Int.Length - 1
For II = 0 To int_Value.Length - 1
If Dum_Int(I) = int_Value(II) Then
STORE_KEYS.Add(int_Key(II))
int_Value(II) = Integer.MaxValue
End If
Next
Next
I got output like..
'' OUTPUT''
(0) 3 {Integer} Object
(1) 5 {Integer} Object
(2) 4 {Integer} Object
(3) 2 {Integer} Object
(4) 6 {Integer} Object
(5) 1 {Integer} Object
(6) 7 {Integer} Object
I assume that I have Hashtable.
I create two arrays and store both Keys (int_Key) and Values(Int_Value) From Hashtable
then I copy Value(Int_Value) array to Dum_Int to sort values
Whenever I found matching int value between Sorted Array and Original Value Array
I stored in to STORE_KEYS(arraylist) and I insert Max Int value to original array to prevent overlapping issue.
However, is there any way to improve this method ?
I don't believe that better sorting algor can't help to simplify this method.
Can you provide any hints to simplify this method?
thanks

The Array.Sort method has an overload that will sort an array based on another array:
Dim keys = myHastable.Keys.Cast(Of Integer)().ToArray()
Dim values = myHastable.Values.Cast(Of Integer)().ToArray()
Array.Sort(values, keys)

Related

Excel VBA: Mysterious Zero is Being Added to Array Created with "For" Loop

Hey everyone: I'm trying to make a function that digs through an array and adds values from range2 when the corresponding value from range1 equals criteria1.
I'm relatively new to VBA, so it's not the most elegant function in the world, but here's my code:
Function SingleArray(range1 As Range, range2 As Range, criteria1 As String)
Dim newrange() As Double
Dim d As Integer
Dim g As Integer
Dim i As Integer
g = Application.WorksheetFunction.CountIf(range1, criteria1)
ReDim newrange(g)
d = 1
For i = 0 To (range1.Count)
If range1(i) = criteria1 Then
newrange(d) = range2.Item(i).Value
d = d + 1
End If
Next i
SingleArray = newrange
End Function
Here is my data sample:
range2 range1
-5000 Bob
-5000 Jim
200 Bob
500 Jim
5000 Bob
200 Bob
300 Bob
1000 Bob
When I set the criteria as "Bob," the array that is returned is as follows:
{0,-5000,200,5000,200,300,1000}
I'm genuinely at a loss for how that zero is making it in there. Any thoughts you can provide would be most welcome!
1-D arrays default to a zero-based index structure (e.g. 0, 1, 2, 3, ....). You are looping through the ranges with a one based index (e.g. 1, 2, 3, 4, ...).
When you declare ReDim newrange(5) you are actually creating an array with six elements, not five (e.g. 0, 1, 2, 3, 4, 5)
You can make all arrays on that code sheet default to a one based index by putting this compiler directive at the top of the code sheet.
Option Base 1
You can also change the way the array is declared on the fly by specifying the Lower Boundary and the Upper Boundary.
ReDim newrange(1 to g)

Read File and store element as array Scala

I am new to Scala and this is the first time I'm using it. I want to read in a textfile with with two columns of numbers and store each column items in a separate list or array that will have to be cast as integer. For example the textfile looks like this:
1 2
2 3
3 4
4 5
1 6
6 7
7 8
8 9
6 10
I want to separate the two columns so that each column is stored in its on list or array.
Lets say you named the file as "columns", this would be a solution:
val lines = Source.fromFile("columns").getLines()
/* gets an Iterator[String] which interfaces a collection of all the lines in the file*/
val linesAsArraysOfInts = lines.map(line => line.split(" ").map(_.toInt))
/* Here you transform (map) any line to arrays of Int, so you will get as a result an Interator[Array[Int]] */
val pair: (List[Int], List[Int]) = linesAsArraysOfInts.foldLeft((List[Int](), List[Int]()))((acc, cur) => (cur(0) :: acc._1, cur(1) :: acc._2))
/* The foldLeft method on iterators, allows you to propagate an operation from left to right on the Iterator starting from an initial value and changing this value over the propagation process. In this case you start with two empty Lists stored as Tuple an on each step you prepend the first element of the array to the first List, and the second element to the second List. At the end you will have to Lists with the columns in reverse order*/
val leftList: List[Int] = pair._1.reverse
val rightList: List[Int] = pair._2.reverse
//finally you apply reverse to the lists and it's done :)
Here is one possible way of doing this:
val file: String = ??? // path to .txt in String format
val source = Source.fromFile(file)
scala> val columnsTogether = source.getLines.map { line =>
val nums = line.split(" ") // creating an array of just the 'numbers'
(nums.head, nums.last) // assumes every line has TWO numbers only
}.toList
columnsTogether: List[(String, String)] = List((1,2), (2,3), (3,4), (4,5), (1,6), (6,7), (7,8), (8,9), (6,10))
scala> columnsTogether.map(_._1.toInt)
res0: List[Int] = List(1, 2, 3, 4, 1, 6, 7, 8, 6)
scala> columnsTogether.map(_._2.toInt)
res1: List[Int] = List(2, 3, 4, 5, 6, 7, 8, 9, 10)

Creating arrays in QTP

I am trying to create an array of integers in QTP ( the ints are 9, 16, 25,34,43). I think the code to instantiate it should be (but I could be wrong since I have never created an array in QTP before),
Dim pages(5)
pages(0) = 9
pages(1) = 16
...
Then I have a for loop with a variable that goes from 1 to 50 and based off of the value of the variable it does one thing and if the variable is one of the values in the array it does something else. For that I have,
For g = 1 to 50
if g<> 9 and g<> 16 and g<> 25 and g<>34 and g<> 43 Then
DoCoolStuff...
else
DoBoringStuff...
End If
Next
My question is, is there a command that will allow me to replace that ugly if statement with something like
if g <> in pages*?
If you want a Dimensioned Array, then that is the only way to declare an array. If you wanted a Non dimensioned array you then can use,
Dim pages()
pages = Array(9, 16, 25, 34, 43)
However, you can also do this,
Dim pages()
ReDim pages(5)
pages = Array(9, 16, 25, 34, 43)
Coming to your problem, you can get this going by using the Filter function. Although there is a very small problem. Filter method takes in String, so even with that function your will match 1, 2, 3, 4, 5, 6 along with the real/actual values 9, 16, 25, 34, 43.
As,
1 occurs in 16.
2 occurs in 25.
3 occurs in 34 and 43.
4occurs in 34 and 43.
5 occurs in 25.
6 occurs in 16.
It still thinks they occur in the String. One way to get around this is to Format the numbers as a two literal. Something like.
Dim pages(), g As Integer
ReDim pages(5)
pages = Array("09", "16", "25", "34", "43")
For g = 1 To 50
If UBound(Filter(pages, Format(g, "00"))) > -1 Then
'Do Cool Stuff here
Else
'Do Boring Stuff here
End If
Next
EDIT :
The other way is to create a User Defined Function that could Loop through your Array and find if the Value is Found in your Array. Something like,
Public Function FindArrayElement(SearchArray As Variant, LookupValue As Integer) As Boolean
Dim aCtr As Integer
For aCtr = 0 To UBound(SearchArray)
If CLng(SearchArray(aCtr)) = LookupValue Then
FindArrayElement = True
Exit Function
End If
Next
FindArrayElement = False
End Function
The function takes in two Arguments. The first is the Array in which the values are defined, the second is the Value looked up for. So your Original code would change to.
Dim pages(), g As Integer
ReDim pages(5)
pages = Array(9, 16, 25, 34, 43)
For g = 1 To 50
If FindArrayElement(pages, g) Then
'Do Cool Stuff here
Else
'Do Boring Stuff here
End If
Next
First, I, too, would suggest to initialize Pages like this:
Dim Pages(): Pages=(9,16,25,34,43)
Second, and independently from the first aspect, you could use this code to check if g is contained in Pages:
Dim Elem
Dim Found: Found=false
For Each Elem in Pages
If Elem = g then
Found=true
Exit For
End If
End For
If Found then
DoBoringStuff
else
DoCoolStuff
End If
The For..Each loop iterates as many times as there are elements in the Pages array. For each iteration, Elem is set to one Pages array element.
Note that the comparison is between Integers, as requested.

Can I create a line graph from an Array?

I have 6 arrays of data as longs. I want to find a way to graph all six arrays as separate lines on a Chart Control.
I have created the Chart object, in my Series Collection Editor I have 6 members, but I cannot find a function that does something along the lines of chart1.series1.setData(myArray).
I know I can go through and call .add() on every point, but I am wondering if there is a direct way to assign an array to a Series.
There is no built in way to add a whole range apart from databinding. You can call, as you said, the AddXY method of the Points property (or one of the related methods in the type DataPointCollection) of the Series, like so:
'Add data from Array1 to the first series of the chart
Chart.Series(0).Points.Clear() 'Clear all points
For i = 0 to Array1.Count - 1
Chart.Series(0).Points.AddXY(i, Array1(i)) 'Adds the data from the array to the first series
Next
If you have the data in a multidimensional (e.g. Dim Data()() As Long) you can do something like
For a = 0 to Data.Count - 1
Chart.Series(a).Points.Clear() 'Clear all points from the ath series
For i = 0 to Data(a).Count - 1
Chart.Series(a).Points.AddXY(i, Data(a)(i)) 'Adds the data from the ath array to the ath series
Next
Next
Note the X values will be just an index (0 to the array's count - 1) since you provided no further information.
Or you could write an extension method in a new Module
Public Module Extensions
<System.Runtime.CompilerServices.Extension>
Public Sub AddRange(d As System.Windows.Forms.DataVisualization.Charting.DataPointCollection, data() As Long)
Dim meCount As Integer = d.Count
For i = 0 To data.Count - 1
d.AddXY(meCount + i, data(i))
Next
End Sub
End Module
Now you can just call the AddRange method for the Points property of the series:
Chart.Series(0).Points.AddRange(Array1)
You can do it by adding point by point as Jens mentions, and this works find. Another way which should work fine is:
For a as integer = 0 to AmountOfSeries.count - 1 step 1
Chart1.Series(a).Points.DataBindXY(ArrayX1, ArrayY1)
Next
This may be closer to what you were looking for - a way to set two arrays to a series.
Here's what it would look like with only one series:
Dim xs As Double() = {0, 1, 2, 3, 4}
Dim ys As Double() = {0, 1, 2, 3, 4}
Chart1.Series(0).Points.DataBindXY(xs, ys)

Sorting an array numerically (VB.NET)

I want to sort records based on their integer value in descending order:
Example:
name1, 4
name2, 6
name3, 3
name4, 5
Should be re - arranged to this:
name2, 6
name4, 5
name1, 4
name3, 3
I've tried using the Array.Sort but I could not get it working.
As always I appreciate all of your help.
You can split the data into two arrays and use use array.sort to sort based on the integers.
Dim a() As String = {"name1", "name2", "name3", "name4"}
Dim ia() As Integer = {4, 6, 3, 5}
Array.Sort(ia, a)
This will sort both arrays in ascending order of ia. Iterate the arrays backward to get descending order.
Sub Main()
Dim StartArray(3) As Integer
'First let's assign the array elements before it is sorted
StartArray(0) = 4
StartArray(1) = 6
StartArray(2) = 3
StartArray(3) = 5
Array.Sort(StartArray) 'This sorts the array
For i As Integer = 0 To 3
Console.WriteLine(StartArray(i)) 'Prints the array elements to console
Next
Console.ReadLine()
End Sub
dim nos() as integer={1,2,3,4}
dim names() as string = {"a","b","c","d"}
for i = 0 to 3
array.sort(names &" "&nos)
next
console.readKey

Resources