Get ListBox and TextBox Matching Values VB.NET - vb.net

I have a listbox1 containing some values
value 1
value 2
value 3
value 4
value 5
and TextBox1 containing some lines
Value 3
Value 5
Value 10
Value 14
I want to get values matching in listbox1 and TextBox1
like
Value 3
Value 5
and perform some action code if values matches and loop until last value match
I have used this code but its not giving accurate output.
Dim compare As String
Dim comparear() As String
Dim list As String
Dim listar() As String
compare = TextBox1.Text
comparear = compare.Split(vbNewLine)
list = TextBox2.Text
listar = list.Split(vbNewLine)
For i = 0 To comparear.Length - 1
For p = 0 To listar.Length - 1
If listar(p).Contains(comparear(i)) Then
txt_match.Text = txt_match.Text & listar(p) & vbNewLine
Else
End If
Next
Next

You can write
Dim result = listBox1.Items.OfType(Of String).Intersect(textBox1.Lines)
result is of type IEnumerable(Of String). I.e., you can use it in For Each or add .ToList or .ToArray to get a collection.
Note that the match is case sensitive. If you want to ignore the case, you can write
Dim result = listBox1.Items.OfType(Of String) _
.Intersect(textBox1.Lines, StringComparer.OrdinalIgnoreCase)
Since the ListBox Items are returned as Objects, I used listBox1.Items.OfType(Of String) to convert them to Strings.
As I can see in the code example that you have added, you are comparing the lines of 2 TextBoxes and joning the result into a 3rd one, You can do it with these 2 code lines
Dim result = textBox1.Lines.Intersect(textBox2.Lines, StringComparer.OrdinalIgnoreCase)
txt_match.Text = String.Join(vbNewLine, result)
If you wanted to compare the items of 2 ListBoxes
Dim r = listBox1.Items.OfType(Of String) _
.Intersect(listBox2.Items.OfType(Of String), StringComparer.OrdinalIgnoreCase)
Intersect works with any two enumerations or collections of the same type
A.Intersect(B)
returns a IEnumerable(Of T) where both A and B are themselves IEnumerable(Of T). So it does not matter whether you are using the lines of a TextBox, the Items of a ListBox casted to T or arrays or List(Of T) or anything else.
Your code does not work because of 2 different errors:
You have Option Strict Off. This hides an error showing you that you are calling the wrong overload of Split. VB tries to convert vbNewLine (which is a String) to a Char, and calls Split with the 1st char found in vbNewLine. Use Option Strict On in your project and you will get a compile error. Write this instead
comparear = compare.Split(New String() {vbNewLine}, StringSplitOptions.RemoveEmptyEntries)
listar = list.Split(New String() {vbNewLine}, StringSplitOptions.RemoveEmptyEntries)
Your match is case sensitive. Instead compare like this
If listar(p).ToLowerInvariant = comparear(i).ToLowerInvariant Then

Related

Is it possible to use String.Split() when NewLine is the delimiter?

I have a question which asks me to calculate something from an input file. The problem is, the lines in the file don't use any special character as delimiter, like , or |. I will show it down below.
Data Communication
20
Visual Basic
40
The output I need to write to another file should look like this:
Data communication 20
Visual Basic 40
Total Books : 60
The problem is, how can I specify the delimiter? Like when there is a symbol as in strArray = strLine.Split(","). Since there is nothing I can use as delimiter, how can I split the file content?
There's no real need to split the text in the input file, when you can read a file line by line using standard methods.
You can use, e.g., a StreamReader to read the lines from the source file, check whether the current line is just text or it can be converted to a number, using Integer.TryParse and excluding empty lines.
Here, when the line read is not numeric, it's added as a Key in a Dictionary(Of String, Integer), unless it already exists (to handle duplicate categories in the source file).
If the line represents a number, it's added to the Value corresponding to the category Key previously read, stored in a variable named previousLine.
This setup can handle initial empty lines, empty lines in the text body and duplicate categories, e.g.,
Data Communication
20
Visual Basic
40
C#
100
Visual Basic
10
Other stuff
2
C++
10000
Other stuff
1
If a number is instead found in the first line, it's treated as a category.
Add any other check to handle a different structure of the input file.
Imports System.IO
Imports System.Linq
Dim basePath = "[Path where the input file is stored]"
Dim booksDict = New Dictionary(Of String, Integer)
Dim currentValue As Integer = 0
Dim previousLine As String = String.Empty
Using sr As New StreamReader(Path.Combine(basePath, "Books.txt"))
While sr.Peek > -1
Dim line = sr.ReadLine().Trim()
If Not String.IsNullOrEmpty(line) Then
If Integer.TryParse(line, currentValue) AndAlso (Not String.IsNullOrEmpty(previousLine)) Then
booksDict(previousLine) += currentValue
Else
If Not booksDict.ContainsKey(line) Then
booksDict.Add(line, 0)
End If
End If
End If
previousLine = line
End While
End Using
Now, you have a Dictionary where the Keys represent categories and the related Value is the sum of all books in that category.
You can Select() each KeyValuePair of the Dictionary and transform it into a string that represents the Key and its Value (Category:Number).
Here, also OrderBy() is used, to order the categories alphabetically, in ascending order; it may be useful.
File.WriteAllLines is then called to store the strings generated.
In the end, a new string is appended to the file, using File.AppendAllText, to write the sum of all books in all categories. The Sum() method sums all the Values in the Dictionary.
Dim newFilePath = Path.Combine(basePath, "BooksNew.txt")
File.WriteAllLines(newFilePath, booksDict.
Select(Function(kvp) $"{kvp.Key}:{kvp.Value}").OrderBy(Function(s) s))
File.AppendAllText(newFilePath, vbCrLf & "Total Books: " & booksDict.Sum(Function(kvp) kvp.Value).ToString())
The output is:
C#:100
C++:10000
Data Communication:20
Other stuff:3
Visual Basic:50
Total Books: 10173
Sure.. System.IO.File.ReadAllLines() will read the whole file and split into an array based on newlines, so you'll get an array of 4 elements. You can process it with a flipflop boolean to get alternate lines, or you can try and parse the line to a number and if it works, then its a number and if not, it's a string. If it's a number take the string you remembered (using a variable) from the previous loop
Dim arr = File.ReadALlLines(...)
Dim isStr = True
Dim prevString = ""
For Each s as String in arr
If isStr Then
prevString = s
Else
Console.WriteLine($"The string is {prevString} and the number is {s}")
End If
'flip the boolean
isStr = Not isStr
Next s
I used File.ReadAllLines to get an array containing each line in the file. Since the size of the file could be larger than the sample shown, I am using a StringBuilder. This save having to throw away and create a new string on each iteration of the loop.
I am using interpolated strings indicated by the $ preceding the quotes. This allows you to insert variables into the string surrounded by braces.
Note the Step 2 in the For loop. i will increment by 2 instead of the default 1.
Private Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click
Dim lines = File.ReadAllLines("input.txt")
Dim sb As New StringBuilder
Dim total As Integer
For i = 0 To lines.Length - 2 Step 2
sb.AppendLine($"{lines(i)} {lines(i + 1)}")
total += CInt(lines(i + 1))
Next
sb.AppendLine($"Total Books: {total}")
TextBox1.Text = sb.ToString
End Sub

Reading a file in and outputting to two listboxes

I'm using Imports System.IO and StreamReader inside a Windows Forms App.
I am trying to take a file, read it in, and output it into two listboxes. The text file is formatted like this.
Blue, 23.7
Green, 60.1
Black, 45.3
I want to output colours that have a higher value than 50 into one listbox, and the ones lower into another. So far all I've done is output the whole list into a textbox. The code for that looks like this:
srTextFile = File.OpenText(dataFile)
Do While srTextFile.EndOfStream = False
'read file by line, use the comma as a splitter
thisFile = srTextFile.ReadLine().Split(",")
For i As Integer = 0 To thisFile.GetUpperBound(0)
txtFileDisplay.AppendText(thisFile(i) &vbTab)
Next
txtFileDisplay.AppendText(vbCrLf)
Loop
I'm completely new to reading in files. I really don't know what I'm doing. I'm pretty new to arrays as well.
Thanks!
By using a class, you can create objects containing the color names as well as the double value and add those to the listboxes.
Public Class ColorValue
Public Property Name As String
Public Property Value As Double
Public Overrides Function ToString() As String
Return $"{Name} ({Value})"
End Function
End Class
Note that I've overridden ToString, because ListBox uses it to display a text for each item.
Now, you can add colors to the listboxes like this
For Each line As String In File.ReadLines(dataFile)
Dim parts As String() = line.Split(","c)
If parts.Length = 2 Then 'If line is well-shaped.
Dim value As Double
Double.TryParse(Trim(parts(1)), value) 'Gets 0 into value if conversion fails.
Dim color = New ColorValue With {.Name = parts(0), .Value = value}
If value > 50.0 Then
listBox1.Items.Add(color)
Else
listBox2.Items.Add(color)
End If
End If
Next
Now, you can get a color value back with
Dim c As ColorValue = DirectCast(listBox1.SelectedItem, ColorValue)
Dim n As String = c.Name
Dim v As Double = c.Value
You can make use of the System.IO.File Class to do this
Simply read the text file into a string
Split the string into lines
Split the lines into arrays
Parse the strings into doubles
Compare the doubles and get values greater than 50 into a seperate listbox
You can write your code like this:
For Each line As String In File.ReadAllLines("Your file here")
Dim Spl() AS String = Split(line, ",")
'Convert string value to integer
Dim myNum As Double = Double.Parse(Spl(1))'The number is the second item in the array
If myNum < 50.0 Then
'Add to your first Listbox here using
'Listbox.Add(myNum)
Else
'Add to your second Listbox here using
'Listbox.Add(myNum)
End If
Next

Parsing through an Array For Next loop Visual Basic

I am stuck here. Spent hours trying many different approaches but nothing is working
I have an array that holds text that looks like this
4456|4450|17
4466|4430|18
4446|4420|19
4436|4410|20
The separator is a pica ("|").
What I am trying to do is run through the array and extract the first two columns in separate strings to compare the values, look for the max, and min.
I am trying to end up with a string like this
4456,4466,4446,4436
Here is the solution:
Dim source As String = prices
Dim stringSeparators() As String = {vbCrLf}
Dim result() As String
result = source.Split(stringSeparators,
StringSplitOptions.RemoveEmptyEntries)
Dim fString As String = String.Join(Of String)(", ", result.Cast(Of String).Select(Of String)(Function(x) x.Split("|")(0)))
MsgBox(fString)
Let's take your example below...
4456|4450|17
4466|4430|18
4446|4420|19
4436|4410|20
prices = [the array shown above]
For Each i As String In prices
high = (i.Split("|"))(0)
highs = highs & highs1 & ","
MsgBox(highs)
Next
The reason you are getting 4,4,5,6,,4,4,5,0,,1,7 is because for each string you are splitting on the | and then taking the first character adding a comma to it.
If you want to get the first column or index whatever you want to call it before the | you need to loop through each string in that array and select out the values...
'this is my test array...
Dim arr As New ArrayList From {"4456|4450|17", "4466|4430|18", "4446|4420|19", "4436|4410|20"}
Now we can use a String.Join function, cast the array for each item as a string and finally select the first item on the split. This will get every item before the | and put them in a string separated with a comma.
Dim fString As String = String.Join(Of String)(", ", arr.Cast(Of String).Select(Of String)(Function(x) x.Split("|")(0)))
If you want the second section select the 1st index as arrays start at 0...
Dim sString As String = String.Join(Of String)(", ", arr.Cast(Of String).Select(Of String)(Function(x) x.Split("|")(1)))
Here is my screenshot of the outputs...

Find the maximum string in Combobox

I am trying to change combobox's DropDownWidth based on maximum string in Combobox's items.
The code below returns the maximum string length from all the items.
Dim maxStringLength As Integer = cboDt.AsEnumerable().
SelectMany(Function(row) row.ItemArray.OfType(Of String)()).
Max(Function(str) str.Length)
cboDt is the datatable attached to combobox.
I want to return the actual string.
For example if combobox items are:
"aaa"
"bbbb"
"ccccc"
My code returns maxStringLength = 5 (because 5 is the maximum number of characters of all items-here is ccccc)
I want code to retun "ccccc" (of course in a string variable)
Order the list by string-length descending, and then take the first result.
Dim maxStringLength As Integer =
cboDt.AsEnumerable().
SelectMany(Function(row) row.ItemArray.OfType(Of String)()).
OrderByDescending(Function(str) str.Length).
First() ' You can use FirstOrDefault here, if you are
' not certain there will be a result.
Assuming that the first column of the DataTable is displayed in the ComboBox:
Dim maxStringLength As Integer = cboDt.AsEnumerable().
Max(Function(r) r.Field(Of String)(0).Length)
Note that this assumes that this requires that this column is never null.
( I don't see a reason why you would measure the length of the (possibly available) other columns of the table when they aren't shown in the ComboBox at all. )
Update
Find the maximum string in Combobox
Now i got it, you want the string not the length:
Dim longestString = cboDt.AsEnumerable().
OrderByDescending(Function(r) r.Field(Of String)(0).Length).
First().Field(Of String)(0)
You can achieve this using linq and Finding the Index of maxStringLength = 5
Dim ls = comboBox4.Items.Cast(Of String)().ToList()
Dim index = ls.FindIndex(Function(c) c.ToString().Count() >= 5)
comboBox4.SelectedIndex = index
or using Max() Method
Dim ls = comboBox4.Items.Cast(Of String)().ToList()
Dim index = ls.Max()
comboBox4.Text = index

compare a string and trim in vb.net

I have this string that shall come in from another file. The string has maximum length of 102 digits. I need to compare the string with numbers in a pair and delete those from that string.
e.g - 6125223659587412563265... till 102
numbers that compare with this string-
first set - 61
new string = 25223659587412563265
second set - 36
new string = 252259587412563265
and so on. the set of numbers shall go to maximum of 51 pairs = 102, which shall give an end result of string = ""
How can i achieve this in a loop?
this is not answer, this is editing the question. i dont know why but the edit button just vaniashed so i have to edit question here.
No duplicates will ever be in this string. and in the end when compares are done, i want to see what numbers are left in pairs.
Dim input As String = "6125223659587412563265"
Dim targets As String() = {"61", "36"}
For Each target As String In targets
input = input.Replace(target, "")
Next
Debug.Assert(input = "252259587412563265")
Here is a simple solution. You will need to add your pairs to the List(Of String) and also initialize input to the string you want to alter.
Dim pairs As New List(Of String)()
Dim input As String = String.Empty
For Each pair As String In pairs
input = input.Replace(pair, String.Empty)
Next