VB使用逗号分隔符将文本从txt文件存储到2D数组

时间:2013-11-21 13:36:12

标签: arrays vb.net file text 2d

我已经找到了答案,但努力使我的调查结果适应我的代码/文本文件。

我有这个文本文件;
20,本
10,戴夫
7,鲍勃

得分和名字。

我想将文本文件中的数据拉入2D数组,例如:

数组(0,0)
数组(1,0)
数组(0,1)
数组(1,1)
数组(0,2)
数组(1,2)

将转化为;

阵列(20)
阵列(本)
阵列(10)
阵列(戴夫)
阵列(7)
阵列(鲍勃)

提前致谢

2 个答案:

答案 0 :(得分:0)

正如我的评论所述,我会使用一个类。

例如Player有两个属性:Name As StringScore As Int32。然后,您可以创建List(Of Player)。这比读取索引更具可读性,可重用性和可维护性,并且更不容易出错。

Public Class Player
    Public Property Name As String
    Public Property Score As Int32
End Class

这是一个可读的LINQ查询,用于从文本文件中的行初始化List(Of Player)

Dim allPlayers = From line In System.IO.File.ReadLines("path")
                 Let Columns = line.Split(","c)
                 Where Columns.Length = 2
                 Let Score = Int32.Parse(Columns(0).Trim())
                 Let Name = Columns(1).Trim()
                 Select New Player With {.Score = Score, .Name = Name}
Dim playerList As List(Of Player) = allPlayers.ToList()

如果您需要数组,请使用ToArray而不是ToList

您可以通过索引器(list(0))或LINQ方法访问数组alist:

Dim firstPlayer As Player = playerList.FirstOrDefault()  ' is Nothing if there are no players '
Console.WriteLine("Name of the player: " & firstPlayer.Name)
Console.WriteLine("His score is: " & firstPlayer.Score)

或循环:

For Each player In playerList
    Console.WriteLine("Player {0} has scored {} points.", player.Name, player.Score)
Next

顺便说一句,LINQ对于保持代码可读性非常有用,它也会使用循环。因此,您只需使用OrderByDescendending按分数排序您的玩家,并以最高分数输出前3名:

Dim best3Players = From player In playerList
                   Order By Player.Score Descending
                   Take 3
                   Select String.Format("{0}({1})", player.Name, player.Score)
Dim output = String.Join(", ", best3Players)
Windows.Forms.MessageBox.Show(output) ' since you have mentioned messagebox '

答案 1 :(得分:0)

如果您知道该文件不会非常大,最简单的方法是简单地使用File.ReadAllLines方法,该方法返回一个包含文件中每行一项的单维字符串数组。然后,您可以遍历每一行并使用String.Split方法将这两个值从行中拆分,例如:

Dim lines() As String = File.ReadAllLines("leaderboard.csv")
Dim values(lines.Length - 1, 1) As String
For i As Integer = 0 to lines.Length - 1
    Dim parts() As String = lines(i).Split(","c)
    values(i, 0) = parts(0)
    values(i, 1) = parts(1)
Next

但是,如果您创建一个类来存储每行的所有数据会更好,如下所示:

Public Class LeaderboardEntry
    Public Property PlayerName As String
    Public Property Score As Integer
End Class

然后,您可以将值加载到这些对象的列表中,如下所示:

Dim entries As New List(Of LeaderboardEntries)()
For Each i As String In File.ReadAllLines("leaderboard.csv")
    Dim parts() As String = lines(i).Split(","c)
    Dim entry As New LeaderboardEntry()
    entry.Score = parts(0)
    entry.PlayerName = parts(1)
    entries.Add(entry)
Next

然后,不要说values(0, 0)来获得第一个条目的分数,而是说entries(0).Score,它更具可读性,特别是如果您为文件中的每一行添加更多字段。有关使用类的功能的更多信息,请查看我对this question的回答。

但请记住,上面的代码假定每行都格式正确。如果文件包含任何不包含逗号的行,则会失败。如果您需要处理这种情况,则需要添加一些额外的检查。此外,在上面的场景中,玩家名称不能包含任何逗号。处理这种情况的最佳方法是使用正确的CSV格式,如下所示:

30,"Doe, John"

然后你的引号需要转义等等,在这种情况下,使用TextFieldParser类来读取CSV文件而不是重新发明轮子是值得的。另一种选择是简单地禁止用户在其名称中输入逗号。但是,如果采用这种方法,最好为分隔符选择一个不常用的字符,例如管道符号(|)。

我建议使用XML文件,而不是使用CSV文件。然后,您可以轻松地存储数据,即使它的复杂性增加,也可以使用XmlSerializerXmlDocumentXDocument来读取和写入数据。

如果你需要做的就是存储这样的简单值,那么更好的选择可能就是使用My.Settings功能。