Eliminate duplicate from a Multi-Line string - vb.net

I have a text-box control called Textbox1 which contains the following items (in a Multi-line string):
22,23
57,58
20,21
51,52
57,58
20,21
21,22
25,26
35,36
41,42
50,51
22,23
23,24
37,38
44,45
45,46
67,68
72,73
78,79
How do I remove 2-digit duplicates? Instead of 20,21, it does not appear twice and once. If the combination of 2 numbers still exists in another line, then this combination appears once. and so on.

Private Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click
Dim lines() As String = TextBox1.Text.Split(New String() {vbCrLf, vbCr, vbLf}, StringSplitOptions.None)
Dim repeatedElement As String = ""
'First have to sort array
System.Array.Sort(lines)
For Each Line As String In lines
If Not (String.Compare(Line, repeatedElement) = 0) Then
TextBox2.Text += Line & vbCrLf
End If
repeatedElement = Line
Next
End Sub
Here textBox1 is for source text and textBox2 is for result.

Related

reading from txt file and writing in textbox

Can somebody help me with this, im stuck no idea what to do next
give a text file at any location in the computer it contains 15 different integers that can be repeated
make the program so that multiple repetitions of one number are not printed separately, but each number is printed exactly once
and next to it are written in which places he appeared
Imports System.IO
Public Class form1
Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click
Dim povratnaVrijednost As DialogResult
Dim nazivDatoteke As String
Try
OpenFileDialog1.AddExtension = True
OpenFileDialog1.Multiselect = False
OpenFileDialog1.Filter = "Tekst datoteke (*.txt)|*.txt;"
povratnaVrijednost = OpenFileDialog1.ShowDialog()
If povratnaVrijednost = Windows.Forms.DialogResult.OK Then
If OpenFileDialog1.CheckFileExists = True And
OpenFileDialog1.CheckPathExists = True Then
nazivDatoteke = OpenFileDialog1.FileName
TextBox1.Text = nazivDatoteke
Dim citac As New StreamReader(nazivDatoteke)
Dim redTeksta As String = ""
Do
redTeksta = citac.ReadLine()
If Not redTeksta Is Nothing Then
RichTextBox1.Text = RichTextBox1.Text + redTeksta
End If
Loop Until redTeksta Is Nothing
citac.Close()
End If
End If
Catch ex As Exception
MsgBox("Greska prilikom otvaranja" + ex.StackTrace.ToString)
End Try
End Sub
End Class
123
Requirement #1:
give a text file at any location in the computer it contains 15 different integers that can be repeated
This requirement implies a couple of other requirements. First, you're expected to read the text file. Second, you're expected to parse the values into numbers (presumably integers).
You can use an OpenFileDialog (documentation) and specify that it can only accept text files:
Using browseFileDialog = New OpenFileDialog()
With browseFileDialog
.Filter = "*.txt|*.txt"
If (.ShowDialog() = DialogResult.Ok) Then
'.FileName will be the text file that the user picked
End If
End With
End Using
To read the text file, assuming you want each line, use the File.ReadAllLines method (documentation):
Using browseFileDialog = New OpenFileDialog()
With browseFileDialog
.Filter = "*.txt|*.txt"
If (.ShowDialog() = DialogResult.Ok) Then
Dim lines = IO.File.ReadAllLines(.FileName)
End If
End With
End Using
To parse the values, use the Array.ConvertAll method (documentation) and inside of the predicate use the Integer.Parse method (documentation):
Using browseFileDialog = New OpenFileDialog()
With browseFileDialog
.Filter = "*.txt|*.txt"
If (.ShowDialog() = DialogResult.Ok) Then
Dim lines = IO.File.ReadAllLines(.FileName)
Dim values = Array.ConvertAll(lines, Function(line) Integer.Parse(line))
End If
End With
End Using
Keep in mind that if you wanted to validate that the lines are all valid numbers, instead of assuming that they are, this step would be different. However, you didn't specify that requirement in your original post so I'm not including how to do that.
Requirement #2:
make the program so that multiple repetitions of one number are not printed separately, but each number is printed exactly once
You can use the Random.Next method (documentation) to generate random values. Be sure to declare the new instance of the random object once so that the seed is only set once. To randomly order the values, use the OrderBy method (documentation) passing the random value in the predicate:
Private ReadOnly _random As New Random()
Private Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click
Using browseFileDialog = New OpenFileDialog()
With browseFileDialog
.Filter = "*.txt|*.txt"
If (.ShowDialog() = DialogResult.Ok) Then
Dim lines = IO.File.ReadAllLines(.FileName)
Dim values = Array.ConvertAll(lines, Function(line) Integer.Parse(line))
Dim randomlyOrderedValues = values.OrderBy(Function(value) _random.Next())
RichTextBox1.Text = String.Join(", ", randomlyOrderedValues.ToArray())
End If
End With
End Using
End Sub
Default for .AddExtension is True. Default for .Multiselect is False. I have simplified the If statement by comparing the return value of .Showdialog directly to the desired DialogResult. If the path of file don't exist the dialog will show a waring.
Always scope variables as narrowly as possible. I move the Dim nazivDatoteke to inside the If since it is not used anywhere else. StreamReaders require a Using block since they need to be disposed.
Why a RichTextBox for a text file?
As you can see getting the distince items in the array is easy, a single line of code. What is more difficult is finding the indexes in the original array, lines.
I looped through all the items in the distinct array (actually it is an IEnumerable(Of String) but that is not important to this code, it is just easier to type array in my explanation). I created a List(Of Integer) to hold the indexes of each item in the original array, lines. The startIndex where the FindIndex method of an Array is the location of the first occurrence of the String.
On each iteration of the Do loop I look for the matches to the item from the lines array. The FindIndex takes parameters (original array, index to start at, what we are looking for). It stops as soon as it finds a match and returns -1 if no matches are found. You can see the operation of this method be setting a break point and checking the variable values.
If a match is found I added that value to the list and change the startIndex to the position following the found index.
Next I used a StringBuilder to create the string to display. I chose the immediate window for testing purposes but you could show sb.ToString in a text box or add it to a ListBox.
Private Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click
OpenFileDialog1.Filter = "Tekst datoteke (*.txt)|*.txt;"
If DialogResult.OK = OpenFileDialog1.ShowDialog Then
Dim nazivDatoteke = OpenFileDialog1.FileName
TextBox1.Text = nazivDatoteke
Dim lines = File.ReadAllLines(nazivDatoteke)
Dim distinct = lines.Distinct
For Each item In distinct
Dim lst As New List(Of Integer)
Dim startIndex = Array.IndexOf(lines, item)
Do
Dim FoundIndex = Array.FindIndex(lines, startIndex, Function(line) line = item)
If FoundIndex = -1 Then
Exit Do
Else
lst.Add(FoundIndex)
startIndex = FoundIndex + 1
End If
Loop
Dim sb As New StringBuilder
sb.Append(item)
For Each i In lst
sb.Append($" ({i})")
Next
Debug.Print(sb.ToString)
Next
End If
End Sub
This code displays the distinct items in the list and follow it with the positions (indexes) in the original list.

Detect Unprintable ASCII Characters in String

I'm using Visual Basic 2010 Express. I need to parse a string with unprintable characters in it. I need to detect ASCII 4 (End of Trans).
A scanner dumps data into a TextBox in my app. In a loop, I am using:
If Chr(MyString.Chars(counter)) = 4 Then
MsgBox("Found")
End If
This is not the correct syntax but should convey what I'm trying to do.
After the scanner dumps the data into a textbox:
Private Sub Form1_Load(sender As Object, e As EventArgs) Handles MyBase.Load
TextBox1.Text = "Some chars coming in from " & Chr(4) & " a scanner"
End Sub
Try something like this:
Dim MyString As String = TextBox1.Text
If MyString.Contains(Chr(4)) Then
MessageBox.Show("Found")
End If
Or even something like this:
Dim MyString As String = TextBox1.Text
Dim counter As Integer = 26
If MyString.Chars(counter) = Chr(4) Then
MessageBox.Show("Found")
End If

I want to replace some characters from a string. I used the Replace command. But this is not working

I am writing some code in VB.Net to subtract one string from another string, but this is not working. in output nothing is changed in the target string. But there is no error message. Please help. Thanks.
If RadioButton1.Checked Then
TextBox1.Text = ""
positive = (TextBoxp1.Text + TextBoxp2.Text + TextBoxp3.Text)
negative = (TextBoxn1.Text + TextBoxn2.Text + TextBoxn3.Text)
findstring = Replace(positive, negative, "")
TextBox1.Text = findstring
End If
The concatenation symbol in vb.net is the ampersand (&). You may get unexpected results it you use the plus sign and the strings contain numbers. Parenthesis are not necessary to evaluate an expression except to establish order of calculation when it conflicts with order of precedence.
You are using the vb.net Strings.Replace method. I would use the .net String.Replace method because it is easier to move between .net languages when you get used to using .net methods instead of vb specific methods.
This method takes the original string in this case negative and looks for the entire positive string. If it finds the entire string it replaces it with the empty string.
Private Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click
Dim positive = "b" & "cd" & "ef"
Dim negative = "abc" & "def" & "ghi"
TextBox1.Text = negative.Replace(positive, "")
'Result is aghi
End Sub
If you are trying to remove individual letters from a string then you will have to use a loop. Luckily for us a String is an array of Char.
Private Sub Button2_Click(sender As Object, e As EventArgs) Handles Button2.Click
Dim positive = "ceg"
Dim negative = "abcdefg"
For Each ch As Char In positive
negative = negative.Replace(ch, "")
Next
TextBox1.Text = negative
'Result abdf
End Sub
You are making this way too complicated. If what you want is to remove a substring from within a string use replace like this:
Private Sub Button1_Click(sender As Object, e As EventArgs) Handles btnRemove.Click
If rdbtnRemove.Checked Then
txtResultString.Text = Replace(txtLargeString.Text, txtSearchString.Text, "")
End If
End Sub
All you need is two radio buttons, three text boxes and a button. If you enter 1121221114141 in the txtLargeString text box, 2122 in the txtSearchString text box and execute the code, the result is 111114141 which is the result of removing the txtSearchString input from the txtLargeString input.
Or if as #Mary suggested you want to use the more modern version of replace use this code:
Private Sub Button1_Click(sender As Object, e As EventArgs) Handles btnRemove.Click
If rdbtnRemove.Checked Then
txtResultString.Text = txtLargeString.Text.Replace(txtSearchString.Text, "")
End If
End Sub

Select random person from text file and change corresponding values

I have a form with a button and a label. I also have a text file with the following contents:
Bob:Available:None:0
Jack:Available:None:0
Harry:Available:None:0
Becky:Unavailable:Injured:8
Michael:Available:None:0
Steve:Available:None:0
Annie:Unavailable:Injured:12
Riley:Available:None:0
The values in the text file are:
person-name:available-or-unavailable:sick-or-injured:months-they-will-be-unavailable
What I would like to do is to have the user click the button and a random (available) person will be selected from the text file. The label's text will then say:
personname & " has gotten injured and will be unavailable for 10 months."
I would then like to overwrite the text file with the corresponding values for that particular person. For example that person's second value will now be "Unavailable", the third value will be "Injured" and the fourth value will be 10.
I hope this makes sense.
I don't have any code, as I literally have no idea how to do this. Any help would be much appreciated!
Explanations and code in line.
Private r As New Random
Private RandomIndex As Integer
Private dt As New DataTable
Private Sub Form1_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
AddColumnsToDataTable()
FillDataTable()
End Sub
Private Sub AddColumnsToDataTable()
'Need to prepare the table to receive the data
dt.Columns.Add("Name")
dt.Columns.Add("Available")
dt.Columns.Add("Injury")
dt.Columns.Add("Months")
End Sub
Private Sub FillDataTable()
'ReadAllLines returns an array of lines in the text file
Dim lines = File.ReadAllLines("workers.txt")
'Loop through each line in the lines array
For Each line As String In lines
'.Split returns an array based on splitting the line
'by the colon. The c following ":" tells the compiler
'that this is a Char which the split function requires.
Dim items = line.Split(":"c)
'We can add a row to the data table all at once by
'passing in an array of objects.
'This consists of the elements of the items array
dt.Rows.Add(New Object() {items(0), items(1), items(2), items(3)})
Next
'Now we have an in memory DataTable that contains all the data from the text file.
End Sub
Private Function GetRandomWorker() As String
'A list of all the row indexes that are available
Dim AvailableList As New List(Of Integer)
For i As Integer = 0 To dt.Rows.Count - 1
'Loop through all the data in the date table row by row
If dt.Rows(i)("Available").ToString = "Available" Then
'Add only the row indexes that are Available
AvailableList.Add(i)
End If
Next
'Get a random index to use on the list of row indexes in IndexList
If AvailableList.Count = 0 Then
'No more workers left that are Available
Return ""
End If
'Get a random number to use as an index for the available list
Dim IndexForList = r.Next(AvailableList.Count)
'Selects a row index based on the random index in the list of Available
RandomIndex = AvailableList(IndexForList)
'Now use the index to get information from the row in the data table
Dim strName = dt.Rows(RandomIndex)("Name").ToString
Return strName
End Function
Private Sub SaveDataTable()
'Resave the whole file if this was a real app you would use a database
Dim sb As New StringBuilder
'A string builder keeps the code from creating lots of new strings
'Strings are immutable (can't be changed) so every time you think you are
'changing a string, you are actually creating a new one.
'The string builder is mutable (changable)
For Each row As DataRow In dt.Rows
'The ItemsArray returns an array of objects containing all the
'values in each column of the data table.
Dim rowValues = row.ItemArray
'This is a bit of Linq magic that turns the values into strings
Dim strRowValues = From s In rowValues
Select DirectCast(s, String)
'Now that we have strings we can use the String.Join with the colon
'to get the format of the text file
sb.AppendLine(String.Join(":", strRowValues))
Next
'Finally we change the StringBuilder to a real String
'The workers.txt is stored in the Bin\Debug directory so it is current directory
'no additional path required
File.WriteAllText("workers.txt", sb.ToString)
End Sub
Private Sub Form1_FormClosing(sender As Object, e As FormClosingEventArgs) Handles MyBase.FormClosing
SaveDataTable()
End Sub
Private Sub Button2_Click(sender As Object, e As EventArgs) Handles Button2.Click
Dim WorkerName As String = GetRandomWorker()
If WorkerName = "" Then
MessageBox.Show("There are no available workers")
Return
End If
Label1.Text = $"{WorkerName} has gotten injured and will be unavailable for 10 months."
dt.Rows(RandomIndex)("Available") = "Unavailable"
dt.Rows(RandomIndex)("Injury") = "Injured"
dt.Rows(RandomIndex)("Months") = "10"
End Sub

Advanced Replacement Freeze

Basically I'm creating a tool which while is looking through lines of "file.txt" to replace a word from a textbox's content with that line if the line is containing that word.
Basically if the line is: pizza-cheese-potatoes, all the words containing "pizza" or "cheese" or "potatoes" to be replaced with "pizza-cheese-potatoes"
Here is what I have until now. But it freeze and I don't really know why. Please help me. :)
Dim PATH As String = "C:\test.txt"
Sub Repl(x As String)
For Each line As String In File.ReadLines(PATH)
Dim myList = New List(Of String)(line.Split("|"c))
For Each item As String In myList
If x Is item Then
TextBox1.Text.Replace(x, line)
End If
Next
Next
End Sub
Private Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click
For Each word As String In TextBox1.Text.Split(" "c)
Repl(word)
Next
End Sub
Thank you in advance!
Try doing it like this instead.
Public Sub DoWork()
Dim lines = IO.File.ReadAllLines(PATH)
For Each line In lines
Dim myList = New List(Of String)(line.Split("-"c))
For Each item In myList
If TextBox1.Text.Contains(item) Then
TextBox1.Text = TextBox1.Text.Replace(item, line)
End If
Next
Next
End Sub
Your reader reads the file multiple times which is massively inefficient. This code reads it once, then we just loop over each line with no need to worry about exit conditions etc.
However it's not really doing anything useful as you're not pausing after each line so you'll only be able to review the final one.
There is also no need to test if the textbox contains the text, just simply do a replace then you only search the text once.
For Each item In myList
TextBox1.Text = TextBox1.Text.Replace(item, line)
Next
-------- edit --------
To fix the issue with replacing the word you've already replaced you could try using a replacement placeholder.
For Each item In myList
TextBox1.Text = TextBox1.Text.Replace(item, "#")
Next
TextBox1.Text = TextBox1.Text.Replace("#", line)
---------- edit 2 ------------------
You want to try and build up a new string, word by word, instead of replacing the text in the textbox. This is so that words you've substituted already don't get converted.
Function ReplaceWord(word As String, lines As String())
For Each line As String In File.ReadLines(PATH)
Dim myList = New List(Of String)(line.Split("|"c))
For Each item As String In myList
If word = item Then
Return line
End If
Next
Next
Return word
End Function
Private Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click
Dim result As New System.Text.StringBuilder
Dim lines = File.ReadLines(PATH)
For Each word As String In TextBox1.Text
result.Append(ReplaceWord(word, lines)).Append(" ")
Next
Textbox1.Text = result.ToString()
End Sub