[英]how can I reference multiple columns in a single row within a DataTable as a two-dimensional array?
基本问题是如何在DataTable的一行中将多个连续列引用为可以使用For-Next结构进行处理的二维数组? 这是背景:
所涉及的程序从.csv文件加载数据,其中每行/每行包含有关某人的基本身份信息,其后为对两个问题的数字答案。 程序在.csv文件的每一行中循环,并标识出与当前行的确切答案匹配次数最高的其他五行。
DataTable似乎是将.csv文件读入的最佳结构,但是不确定如何将每一行的最后x列作为答案(人,问题)的数组引用。
万一这看起来真的很简单或完全不切实际,我应该声明以下内容:程序代码已经编写并且可以运行,但是我正在从QuickBASIC 4重新编码它(是的,我确实说过QB4。 ..)到VB.NET。 该程序基本上是一个约会程序,在过去的20多年中,我每年都运行一次,本地学校以筹款的形式出售火柴。 到Windows 7或Windows XP的最新修补程序版本都无法运行QB4的地步,所以我下载了VS Express for Desktop,并将其作为学习VB.NET的机会。 我已经做过很多(非窗口式的)VBScript应用程序脚本,但是我对传统VB的唯一经验是对VB6的一些浅尝light止。 众所周知,.NET中的文件I / O与VB6或更早的版本完全不同。 那就是我现在正在战斗的……
.....
要回答Zohar的问题/评论:
下面是.csv文件格式的示例。 实际文件的长度为几百行,但格式完全相同。 为了保护隐私,姓名和电话号码已更改。 字段依次为:
姓
名字
电话号码(如果提供,则使用占位符,否则)
性别(1 = M; 2 = F)
对问题1(1-4)的回答
对问题2(1-4)的回答
....
对问题24(1-4)的回答
Mouse,Mickey,xxx-xxxx,1,2,3,3,2,3,1,3,4,2,1,4,3,1,1,2,1,2,1,1,1,2,1,1,4
Mouse,Minnie,555-9931,2,1,3,1,2,1,2,3,3,3,4,4,2,4,1,2,3,4,4,4,1,2,1,1,4
Duck,Donald,555-7024,1,2,3,4,2,4,3,4,2,2,1,4,2,4,1,2,1,1,2,1,3,2,1,1,1
McDuck,Scrooge,555-4824,1,2,3,3,2,1,2,4,3,2,4,4,2,4,1,4,2,2,4,4,3,2,1,1,4
GoodWitch,Wendy,xxx-xxxx,2,2,2,4,2,1,2,4,4,3,4,2,2,1,1,2,1,1,4,4,4,4,1,3,1
二维数组的原因是创建一个按用户和问题编号回答的单变量数据库。 有关实际现有QB4代码的排序部分,请参见下文。 我要带入VB.NET标准的二维数组是StudentAnswer(matchFrom,问题)。
For matchFrom = 1 To numberSheets
'
'The following section of code finds the top maximumToMatch groups of n
'matching questions per sheet
'
For x = 1 To maximumToMatch
topMatches(x) = 0
sheetsMatched(x) = 0
Next x
For matchTo = 1 To numberSheets
If StudentSex(matchFrom) <> StudentSex(matchTo) Then
numberMatched(matchTo) = 0
highMatch = 0
For question = 1 To numberQuestions
If StudentAnswer(matchFrom, question) = StudentAnswer(matchTo, question) Then
numberMatched(matchTo) = numberMatched(matchTo) + 1
End If
Next question
If numberMatched(matchTo) = topMatches(1) Then
sheetsMatched(1) = sheetsMatched(1) + 1
End If
If numberMatched(matchTo) > topMatches(1) Then
match = maximumToMatch
done = False
Do
If numberMatched(matchTo) = topMatches(match) Then
sheetsMatched(match) = sheetsMatched(match) + 1
done = True
End If
If numberMatched(matchTo) > topMatches(match) Then
For x = 1 To match - 1
topMatches(x) = topMatches(x + 1)
sheetsMatched(x) = sheetsMatched(x + 1)
Next x
topMatches(match) = numberMatched(matchTo)
sheetsMatched(match) = 1
done = True
Else
match = match - 1
End If
Loop Until done
End If
Else
numberMatched(matchTo) = 0
End If
Next matchTo
...
<additional code to narrow it down to a fixed number of sheet matches>
Next matchFrom
并预期另外两个可能的问题:
编写现有代码以使M与F匹配,反之亦然。 我想在重写过程中使它更加灵活,但这是农村地区,我不确定他们是否已经为此做好了准备...
数据文件为.csv格式的原因是缺少为程序编写的正式数据输入前端。 这一直在待办事项列表上,但是与此同时,由于它每年只运行一次,因此Excel一直是我的朋友...如果一切顺利,我将在VB.NET re期间设计一个数据输入屏幕-写。
在此先感谢所有抽出宝贵时间阅读本文的人。
现在可以使用LINQ(因为.NET 3.5,所以不是新的)来查询对象列表,使用DataTable
可能不是最佳选择,因为数据来自CSV文件而不是数据库(也可以使用LINQ)用于数据库)。
因此,这实际上不是您原始问题的答案,但是如果您输入了以下内容:
Joe User,1,2,3,4,5
Jane User,2,2,3,4,6
Jack User,3,4,5,2,8
Jill User,5,3,1,8,6
您可以定义一个类来存储数据:
Public Class UserInfo
Public Property Name As String
Public Property Answers As List(Of Integer) = New List(Of Integer)()
Public Function MatchRating(other As UserInfo) As Integer
Dim rating As Integer = 0
For i = 0 To Me.Answers.Count - 1
If Me.Answers(i) = other.Answers(i) Then
rating += 1
End If
Next
Return rating
End Function
End Class
然后,您可以将CSV数据读入UserInfo
对象的列表:
Dim users = File.ReadLines("Data.csv").Select(
Function(line)
Dim parts = line.Split(","c)
Dim user = New UserInfo() With {.Name = parts(0)}
user.Answers.AddRange(parts.Skip(1).Select(Function(str) CInt(str)))
Return user
End Function
).ToList()
然后,您可以找到类似以下内容的最佳匹配项,该匹配项循环遍历用户并使用LINQ查询根据匹配的答案数( UserInfo.MatchRating
函数)找到前5个匹配项,并跳过所有不匹配的匹配项( rating > 0
):
For Each user In users
Console.WriteLine("{0}:{1}", user.Name, String.Join(",", user.Answers))
Dim bestMatches = From u In users
Where u IsNot user
Let rating = u.MatchRating(user)
Where rating > 0
Order By rating Descending
Take 5
Select New With {.Name = u.Name, .Rating = rating}
For Each match In bestMatches
Console.WriteLine(" Match: {0}, rating: {1}", match.Name, match.Rating)
Next
Next
您需要将属性添加到UserInfo
类的真实身份信息,并调整代码相匹配。
您还需要确保正确设置了项目选项,并且需要适当的导入/引用,例如:
Option Explicit On
Option Infer On
Option Strict On
Imports System.IO
作为参考,我的测试结果为(杰克可怜,我想您可能需要针对性偏好进行调整,例如Where u IsNot user AndAlso u.Sex <> user.Sex
):
Joe User:1,2,3,4,5
Match: Jane User, rating: 3
Jane User:2,2,3,4,6
Match: Joe User, rating: 3
Match: Jill User, rating: 1
Jack User:3,4,5,2,8
Jill User:5,3,1,8,6
Match: Jane User, rating: 1
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.