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

好久不见. 提交于 2021-01-29 15:24:14

问题


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?


回答1:


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



回答2:


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



回答3:


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


来源:https://stackoverflow.com/questions/65372870/is-it-possible-to-use-string-split-when-newline-is-the-delimiter

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!