我正在尝试在vb.net(表单)中创建一个程序来处理来自UVvis光谱仪的数据。
txt文件输出如下所示。
"180809_QuartzRefTrans.spc - RawData" "Wavelength nm.","T%" 400.00,90.822 401.00,90.800 402.00,90.823 403.00,90.811 404.00,90.803 405.00,90.804 406.00,90.816 407.00,90.811 408.00,90.833 409.00,90.837 410.00,90.847 411.00,90.827 412.00,90.839 413.00,90.851 414.00,90.828 415.00,90.879 416.00,90.846
等等。
我想要做的是将数据读入数组,以便我可以操作列。我需要能够跳过前两行,这样我所拥有的就是数字数据。我还需要它从最低到最高(波长)对数组进行排序。有时我们从800到200纳米运行,然后不小心放入200-> 800纳米
Imports System.IO
Imports System.Windows.Forms.DataVisualization.Charting
Public Class Form1
Public Class RefTrans
Public Property Wavelength As Double
Public Property Transpercent As Double
End Class
Private Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click
Dim strtext As String
OpenFileDialog1.Title = "Open Text Files"
OpenFileDialog1.ShowDialog()
strtext = OpenFileDialog1.FileName
TextBox1.Text = My.Computer.FileSystem.GetName(strtext)
Label1.Text = My.Computer.FileSystem.GetName(strtext)
Dim line1 As String
Dim output1 As New ArrayList
Using sr As New IO.StreamReader(strtext)
sr.ReadLine()
sr.ReadLine()
Do While sr.Peek() >= 0
line1 = sr.ReadLine()
output1.Add(line1)
Loop
End Using
If strtext <> "" Then
Dim SR As New StreamReader(strtext)
SR.ReadLine()
Do Until SR.EndOfStream
TextBox3.Text = TextBox3.Text & SR.ReadLine & vbCrLf
Loop
SR.Close()
End If
Dim data1 = IO.File.ReadLines(strtext).
Skip(2).
Select(Function(line)
Dim parts = line.Split(","c)
Return New RefTrans With {.Wavelength = CDbl(parts(0)),
.Transpercent = CDbl(parts(1))}
End Function).
ToArray() = line.Split(","c)
End Sub
End Class
这是一个可以获得Tuple(Of Double, Double)
数组的示例:
Dim data = IO.File.ReadLines(filePath).
Skip(2).
Select(Function(line)
Dim parts = line.Split(","c)
Return Tuple.Create(CDbl(parts(0)), CDbl(parts(1)))
End Function).
ToArray()
IO.File.ReadLines
方法将读取文件的行。在ReadAllLines
方法读取整个文件然后将行作为String
数组返回的情况下,ReadLines
方法将文件的行公开为可枚举列表,并且只有在您使用它们时才会从文件中读取这些行。特别是对于大文件,ReadLines
比ReadAllLines
更有效,因为它确实创建了一个你实际上并不想要的中间数组。
Skip
方法允许您访问从特定索引开始的列表中的项目。在读取文件的情况下,您需要读取每一行,但是在Skip(2)
的结果上调用File.ReadLines
意味着在读取后将丢弃文件的前两行,并且任何后续处理将仅在第三行的行上完成。
Select
方法基本上是一种转换。它表示创建一个输出列表,其中包含输入列表中每个项目的项目,其中输出项目是输入项目转换的结果。转换由您提供的功能定义。在这种情况下,文件中的一行是输入,转换是在逗号上拆分该行,将两个子串转换为Double
值,然后创建包含这两个Tuple
值的Double
。
ToArray
方法接受任何可枚举列表,即实现IEnumerable(Of T)
的任何对象,并返回包含该列表中的项的数组。在这种情况下,Select
返回一个IEnumerable(Of Tuple(Of Double, Double))
所以ToArray
返回一个Tuple(Of Double, Double)
数组。
如果你想把它全部写成长手,那么它看起来像这样:
'Get all the lines of the file.
Dim step1 As IEnumerable(Of String) = IO.File.ReadLines(filePath)
'Skip the first two lines.
Dim step2 As IEnumerable(Of String) = step1.Skip(2)
'Split each line into two substrings.
Dim step3 As IEnumerable(Of String()) = step2.Select(Function(line) line.Split(","c))
'Convert substrings to numbers and combine.
Dim step4 As IEnumerable(Of Tuple(Of Double, Double)) = step3.Select(Function(parts) Tuple.Create(CDbl(parts(0)), CDbl(parts(1))))
'Create an array of Tuples.
Dim data As Tuple(Of Double, Double)() = step4.ToArray()
Tuple
基本上是用于将值组合在一起的通用对象。您可以将Tuple
用于一次性案例,而不是定义自己的类。您可能更喜欢在所有情况下定义自己的类,并且您应该定义自己的类,您将广泛使用这些数据。在这种情况下,您自己的类可能如下所示:
Public Class RefTrans
Public Property Wavelength As Double
Public Property TransPercent As Double
End Class
然后代码将成为:
Dim data = IO.File.ReadLines(filePath).
Skip(2).
Select(Function(line)
Dim parts = line.Split(","c)
Return New RefTrans With {.Wavelength = CDbl(parts(0)),
.TransPercent = CDbl(parts(1))}
End Function).
ToArray()
在这种情况下,您在数组的每个元素上都有属性Wavelength
和TransPercent
。如果您使用Tuples
,则属性具有通用名称Item1
和Item2
。
一旦你有了数组,你可以使用任何适当的Array.Sort
重载来进行排序,例如
Array.Sort(data, Function(d1, d2) d1.Item1.CompareTo(d2.Item1))
这将通过比较包含波长值的Tuples
属性来对Item1
进行排序。如果您正在使用自己的课程,那么显然您指定了自己的属性,例如我展示了Wavelength
课程中的RefTrans
属性。
• 如何使用 Liquid Template 中的日期函数获取参考当前日期的过去或未来日期?
• 我正在尝试从 C 中的文件中读取,我已经调试了所有错误,除了一个我无法弄清楚的错误
• 如何将固定路径合并到本地 pc 或网络地址,并将单元格值作为文件名
• 为什么我的按钮文本没有根据我在 Vue JS 中的计算方法动态变化?
• 从 MySQL 数据库中提取数据到 NextJS 应用程序,同时将其导出为默认值
• 如何在 Android XML 中使用 drawable 制作圆形背景?
• Kivy asyncio 和 open_settings()
• 想要通过对交易表的查询在单个结果表中按日期按日期汇总多个日期的组织数据