我有一个DataTable(目前有多列但我可以抓住一列,如果它更容易).我想检查String一列中是否存在值DataTable.(我这么做很多次,所以我希望它的速度相当快.)
有什么好办法呢?DataTable每次迭代行似乎都是一种糟糕的方式.我可以将列转换为平面List/Array格式,并使用内置函数吗?有点像myStrList.Contains("value")?
小智 16
您可以select用来查找该值是否存在.如果是这样,它返回行或不会.这里有一些示例代码可以帮助您.
Dim foundRow() As DataRow
foundRow = dt.Select("SalesCategory='HP'")
Run Code Online (Sandbox Code Playgroud)
Ste*_*art 10
如果您的数据DataTable不经常更改,并且您DataTable多次搜索,并且您DataTable包含许多行,那么为数据构建自己的索引可能要快得多.
最简单的方法是按键列对数据进行排序,以便您可以在排序列表上进行二进制搜索.例如,您可以构建这样的索引:
Private Function BuildIndex(table As DataTable, keyColumnIndex As Integer) As List(Of String)
Dim index As New List(Of String)(table.Rows.Count)
For Each row As DataRow in table.Rows
index.Add(row(keyColumnIndex))
Next
index.Sort()
Return index
End Function
Run Code Online (Sandbox Code Playgroud)
然后,您可以使用二进制搜索快速检查索引中是否存在值,如下所示:
Private Function ItemExists(index As List(Of String), key As String) As Boolean
Dim index As Integer = index.BinarySearch(key)
If index >= 0 Then
Return True
Else
Return False
End If
End Function
Run Code Online (Sandbox Code Playgroud)
您也可以使用简单的字符串数组执行相同的操作.或者,您可以使用Dictionary对象(这是哈希表的实现)来构建您的哈希索引DataTable,例如:
Private Function BuildIndex(table As DataTable, keyColumnIndex As Integer) As Dictionary(Of String, DataRow)
Dim index As New Dictionary(Of String, DataRow)(table.Rows.Count)
For Each row As DataRow in table.Rows
index(row(keyColumnIndex)) = row
Next
Return index
End Function
Run Code Online (Sandbox Code Playgroud)
然后,您可以获得DataRow给定键的匹配,如下所示:
Dim index As Dictionary(Of String, DataRow) = BuildIndex(myDataTable, myKeyColumnIndex)
Dim row As DataRow = Nothing
If index.TryGetValue(myKey, row) Then
' row was found, can now use row variable to access all the data in that row
Else
' row with that key does not exist
End If
Run Code Online (Sandbox Code Playgroud)
您可能还想研究使用SortedList或者SortedDictionary类.这两者都是二叉树的实现.在您的特定情况下,很难说所有这些选项中哪一个最快.这一切都取决于数据的类型,索引需要重建的频率,搜索频率,行数,行DataTable以及找到的项目需要做什么.最好的办法是在测试用例中尝试每一个,看看哪个最适合你需要的.
您应该使用行过滤器或DataTable.Rows.Find()而不是select(select不使用索引).根据您的表结构,特别是如果您的字段被索引(本地),任何一种方式的性能应该比循环遍历所有行要快得多.在.NET中,一组字段需要是要成为索引的PrimaryKey.
如果你的字段没有编入索引,我会避免使用select和row过滤器,因为除了类复杂性的开销之外,它们不提供编译时检查你的条件是否正确.如果它很长,你最终可能会花很多时间调试它.
最好将您的支票严格打印.首先定义了一个底层类型,你也可以定义这个helper方法,你可以在以后转换为DataTable类的扩展方法:
Shared Function CheckValue(myTable As DataTable, columnName As String, searchValue As String) As Boolean
For row As DataRow In myTable.Rows
If row(columnName) = searchValue Then Return True
Next
Return False
End Function
Run Code Online (Sandbox Code Playgroud)
或者更通用的版本:
Shared Function CheckValue(myTable As DataTable, checkFunc As Func(Of DataRow, Boolean)) As Boolean
For Each row As DataRow In myTable.Rows
If checkFunc(row) Then Return True
Next
Return False
End Function
Run Code Online (Sandbox Code Playgroud)
及其用法:
CheckValue(myTable, Function(x) x("myColumn") = "123")
Run Code Online (Sandbox Code Playgroud)
如果您的行类具有MyColumn类型的属性String,它将变为:
CheckValue(myTable, Function(x) x.myColumn = "123")
Run Code Online (Sandbox Code Playgroud)
上述方法的一个好处是,您可以将计算字段输入检查条件,因为myColumn这里不需要匹配myColumn表/数据库中的物理.
| 归档时间: |
|
| 查看次数: |
77645 次 |
| 最近记录: |