基本问题是如何在DataTable中引用单行中的多个连续列作为可以使用For-Next结构处理的二维数组?背景是这样的:
有问题的程序从.csv文件加载数据,其中每行/每行都包含关于一个人的基本身份信息,后面是他们对20多个问题的数字答案。该程序循环遍历.csv文件的每一行,并确定与当前行精确答案匹配次数最多的其他五行。
答案似乎是读取问题文件的最佳结构,但是我不确定如何引用每行的最后x列作为.csv (person,DataTable )形式的数组。
如果这看起来真的很简单或者完全不切实际,我应该做以下免责声明:程序代码已经编写好了,并且可以工作,但我正在从QuickBASIC 4重新编码它(是的,我确实说了QB4...)对VB.NET来说,这个项目基本上就是一个约会项目,在过去的20年里,我每年都会运行一次,当地的学校把火柴作为筹款活动出售。它已经到了Windows7和Windows XP的最新补丁版本都不能运行QB4的地步,所以我下载了VS Express for Desktop,并以此作为学习VB.NET的机会。我做了很多(非窗口的) VBScript应用程序脚本编写,但对VB6的一些真正的涉猎是我对传统VB的唯一经验。正如在座的每个人都已经很清楚的那样,.NET中的文件I/O与VB6或之前的版本有很大不同。这就是我现在要抗争的,…
.
要回答Zohar的问题/评论:
以下是.csv文件格式的示例。实际的文件有几百行长,但在形式上完全相同。出于隐私考虑,姓名和电话号码已被更改。这些字段按顺序排列为:
LastName
FirstName
Phone# (如果给定,则为占位符)
性(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代码的排序部分,请参阅下面的内容。下面的二维数组是StudentAnswer(matchFrom,VB.NET ),我试图将其引入到问题标准中。
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重写期间设计一个数据输入屏幕。
提前感谢所有花时间阅读这篇文章的人。
发布于 2014-04-30 01:36:46
既然LINQ可以用来查询对象列表(从CSV 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查询根据匹配的答案数查找前5个匹配项( UserInfo.MatchRating函数),跳过任何没有匹配项的匹配项(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: 1https://stackoverflow.com/questions/23356288
复制相似问题