mhwnbuvkubcbtqalpk
mhwnbuvkubcbtqalpk

Reputation: 3

Load a .txt file that contains 15 numbers, display them and remove duplicates VB.net

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

Answers (2)

Caius Jard
Caius Jard

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

ProgrammingLlama
ProgrammingLlama

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.

Try it online

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()

Try it online

Upvotes: 0

Related Questions