Reputation: 3
As the title says additionally i have to next to them display a number at which point that number originally appeared in text file...so if a number appeared in First line of .txt file and tenth next to that output should be shown 1,10.
So far this is the code i have written.
Even writing solution in c# would be helpful because i can convert it.
Imports System.IO
Public Class Form1
Private Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click
Dim FileReader As StreamReader
Dim results As DialogResult
Dim OpenFileDialog1 As New OpenFileDialog()
results = OpenFileDialog1.ShowDialog
If results = DialogResult.OK Then
FileReader = New StreamReader(OpenFileDialog1.FileName)
textBox1.Text = FileReader.ReadToEnd()
FileReader.Close()
End If
End Sub
End Class
Upvotes: 0
Views: 48
Reputation: 74605
You can read a file into an array with:
Dim lines = IO.File.ReadAllLines("path")
You can iterate over the array with a For loop that knows the line number:
For lineNumber = 0 To lines.Length-1
You can create a Dictionary(Of String, Integer)
that will store the value and the line number, but only if the value hasn't been seen before:
Dim d as New Dictionary(Of String, Integer)
For ....
Dim line = lines(lineNumber)
If Not d.ContainsKey(line) Then d(line) = lineNumber + 1 ' plus one because arrays number from 0 but you seem to want first line numbered as 1
The dictionary will, over the course of enumerating the loop, fill up with unique keys and the line number they were first seen
You can enumerate a dictionary and print it out:
For Each kvp as KeyValuePair in d
'if the file first line was "10 then
Console.WriteLine(kvp.Key) 'prints e.g. "10"
Console.WriteLine(kvp.Value) 'prints e.g. 1
I didn't write the code for you because it really seems like a homework, but give it a go - everything you need is here
ps; This whole thing can pretty much be done in one line using LINQ.. Something like:
IO.File.ReadAllLines(path) _
.Select(Function(s,x) New With {.S = s, .X = x})
.GroupBy(Function(w) w.S) _
.Select(Function(g) $"{g.Key},{g.First()}")
But if this is homework, definitely don't hand this in!
Upvotes: 1
Reputation: 38737
Note that I'm treating the lines as strings, and not numbers. Hopefully this is OK for your purposes.
I would use a HashSet
for this. This will allow you to quickly and easily check if a value has already been seen.
Next, we can introduce a variable to count the line number, and read the file line-by-line instead of all at once:
Dim line As String
Dim row as integer
Dim seenSet As New HashSet(Of string)()
do
line = FileReader.ReadLine()
if line is nothing then
exit do
end if
row = row + 1
loop while not (line is nothing)
Now, we can add the line
value to seenSet
using seenSet.Add(line)
. If it returns true
then we have a new entry, if it returns false
then it is one we have seen before:
// add this code inside the loop and directly below row = row + 1
if seenSet.Add(line) then
Console.WriteLine(CStr(line) + " " + CStr(row))
end if
This will now print the value of the line, a space, and the row number.
If you need to build it into a single string to display in a textbox, we can introduce StringBuilder
// Declare this before the loop (along with your other variables)
Dim result As New StringBuilder()
// Replace Console.WriteLine
result.AppendLine(CStr(line) + " " + CStr(row))
// After the `loop while` line
textBox1.Text = result.ToString()
In the end you should get this:
Dim line As String
Dim row as integer
Dim seenSet As New HashSet(Of string)()
Dim result As New StringBuilder()
do
line = FileReader.ReadLine()
if line is nothing then
exit do
end if
row = row + 1
if seenSet.Add(line) then
result.AppendLine(CStr(line) + " " + CStr(row))
end if
loop while not (line is nothing)
textBox1.Text = result.ToString()
Upvotes: 0