我目前正在使用Visual Basic在Visual Studio 2015中工作,我有一个带有分隔字符串的类,可以在字符串中的位置提取/替换数据,类似于锯齿状数组,最多可达三级。我可以扩展课程以处理超过三个级别,但是现在,我会坚持使用这三个级别。对于熟悉的人来说,这就像PICK mvdbms数据结构。已经构建了在类中读取和写入数据的基类。为了节省空间和权宜之计,我已将编辑后的代码作为参考来帮助解决我的问题。如果需要更多数据,我可以提供全班。另外,如果在讨论这个问题时有一些问题或建议需要改进我的代码,我总是愿意倾听建设性的反馈。
班级:
Public Class MVString
#Region " Properties "
Private Record As String
Default WriteOnly Property MV(ByVal str As String) As MVString
Set
Record = str
End Set
End Property
Default Public Property MV(ByVal AMPos As Integer) As MVString
'Get and set value at top level
End Property
Default Public Property MV(ByVal AMPos As Integer, ByVal VMPos As Integer) As MVString
'Get and set value at middle level
End Property
Default Public Property MV(ByVal AMPos As Integer, ByVal VMPos As Integer, ByVal SMPos As Integer) As MVString
'Get and set value at deepest level
End Property
#End Region
#Region " Constructors "
Public Sub New()
Record = ""
End Sub
Public Sub New(ByVal str As String)
Record = str
End Sub
#End Region
#Region " Methods "
Public Sub Clear()
Record = ""
End Sub
Public Overrides Function ToString() As String
Return Record
End Function
#End Region
#Region " Operators "
Public Shared Widening Operator CType(v As String) As MVString
Return New MVString(v)
End Operator
Public Shared Widening Operator CType(v As MVString) As String
Return v.ToString
End Operator
#End Region
End Class
我的问题是:如何为此类创建可枚举的支持并将其限制为三个级别,以便系统知道它所在的级别以及需要使用哪个分隔符?例如,如果我有以下变量:
Dim DelimitedString As String =" Foo,4,7,1-2,,6 | Bar,4,2,8-7,5,7 | Fly,4,,8-7,5, 7"
顶级的分隔符是" |",第二级是","而最深层次将是" - "。在这个例子中,顶层将是一个数组{" Foo,4,7,1-2,,6"," Bar,4,2,8-7,5,7&# 34;," Fly,4,,8-7,5,7和#34;},第二级将首先枚举上层的第一个元素,并返回{" Foo" ," 4"," 7"," 1-2",""," 6"}等...
关于从哪里开始的任何想法?
更新
我不确定如何将字典纳入课程,所以我已经用我之前提出的内容更新了我的帖子。
Public Function GetEnumerator() As IEnumerator(Of String) Implements IEnumerable(Of String).GetEnumerator
Return New MVStringEnumerator(Record)
End Function
Private Function IEnumerable_GetEnumerator() As IEnumerator Implements IEnumerable.GetEnumerator
Return Me.GetEnumerator()
End Function
Private Class MVStringEnumerator
Implements IEnumerator(Of String)
Private _ThisArray() As String
Private idx As Integer
Public ReadOnly Property Current As String Implements IEnumerator(Of String).Current
Get
Return If(idx < _ThisArray.Count, _ThisArray(idx), DirectCast(Nothing, String))
End Get
End Property
Private ReadOnly Property IEnumerator_Current As Object Implements IEnumerator.Current
Get
Return Me.Current
End Get
End Property
Public Sub New(ByVal record As String)
Select Case True
Case record.Contains("|"c)
_ThisArray = Split(record, "|"c)
Case record.Contains(","c)
_ThisArray = Split(record, ","c)
Case record.Contains("-"c)
_ThisArray = Split(record, "-"c)
End Select
idx = -1
End Sub
Public Sub Reset() Implements IEnumerator.Reset
idx = -1
End Sub
Public Function MoveNext() As Boolean Implements IEnumerator.MoveNext
idx += 1
If idx >= _ThisArray.Count Then Return False
Return True
End Function
End Class
答案 0 :(得分:2)
我认为你对MVStringEnumerator有正确的想法,你最终枚举了一个字符串数组而不是MV分隔字符串。 (作为MVDBMS专家,我理解您的参考资料。)这可能相当简单。我将消除此任务的双重职责,解析分隔符和枚举。
首先将枚举对象缩小到所需动态数组的最低级别:
myValue = myMVString.MV(1,4)
其次,使其可枚举:
mySubValues = myValue.AsEnumerable()
最后,将mySubValues枚举为常见的字符串数组。因此枚举不知道原始动态数组的MV特性。 当然,以上所有内容都可以更优雅地完成,并封装到一个返回所需枚举的方法中,如:
myEnumerable = myMVString.AsEnumerable(1,4)
或者最终只是迭代new MyEnumerable(myMVSTRING(1,4))
之类的内容。
请注意,如果您真的使用MVDBMS,每个平台都有自己的免费类库来执行此类操作:MVSP,UO.NET,QMClient等。所以您可能不需要编写此代码从头开始 - 虽然这是一个很好的练习。
旁注
如果要模拟MV动态数组,则代码使用基数索引0,其中MV使用1。
答案 1 :(得分:0)
我喜欢使用字典
Dim input As String = "Foo,4,7,1-2,,6|Bar,4,2,8-7,5,7|Fly,4,,8-7,5,7"
Dim dict As Dictionary(Of String, String()) = input.Split("|").Select(Function(x) x.Split(",")) _
.GroupBy(Function(x) x(0), Function(y) y.Skip(1).ToArray()) _
.ToDictionary(Function(x) x.Key, Function(y) y.FirstOrDefault())