比较VB.NET中的数组

时间:2009-05-20 13:48:42

标签: sql vb.net arrays

在进入问题的基本要点之前,让我提供一些细节来解释我想要完成的事情。

我有两个数据源 - 一个是包含部件号,描述等的SQL Server。另一个是没有传统意义上的数据库的CAD系统。我要做的是从SQL Server中读出材料清单,并将其与CAD装配图进行比较,以确保CAD系统包含与SQL Server相同的信息。

从SQL Server获取数据非常简单。我查询数据库并填充数据网格。完成。快。容易。

从CAD系统获取数据更为复杂。我必须加载装配图以获取所有零部件的列表,然后加载这些单独的图纸以从图纸中拉出“零件号”属性。这是一个有点耗时且缓慢的过程(不幸的是),因为必须实际访问每个文件。我将这些属性加载到一个数组中(我猜一个列表可能更有效)。

所以现在我有一个带有部件号的数据网格和数组。我需要比较它们并相应地着色网格。如果部件存在于两者中,则网格应保持透明,如果仅存在于网格中,则将该行的颜色设为黄色,如果仅在数组中,则添加红色的行。

我可以说,这意味着在网格的每一行上循环遍历数组。思考过程是这样的:

  1. 将网格默认为黄色行。
  2. 循环通过网格并循环遍历数组进行比较。如果找到匹配项,请将该行透明并从阵列中删除该元素。
  3. 完成第2步后,数组应仅包含在网格中找不到的元素。调整数组大小以删除空元素。
  4. 将数组的元素添加到网格中,并将这些新行的颜色设置为红色。
  5. 这种逻辑的问题在于从性能角度看它似乎很昂贵。当然有更好的方法吗?此外,如果我以某种方式修改网格(如度假村),我必须再次完成该过程。我真的很感激这方面的一些建议。

    谢谢!

    注意:用Visual Studio 2005编写。

4 个答案:

答案 0 :(得分:7)

您可以从字典中加载CAD系统中的数据(按部件号索引)。然后你可以通过网格检查它是否存在于字典中,这是一个快速操作(O(1))。您可以完全按照说法执行操作,删除字典中找到的元素,并在数据网格中添加其余元素。

以下是一些用于创建和使用字典的代码(使用C#样式注释来保留格式):

//First argument is your key type, second is your item type
Dim cadParts As New Dictionary(Of Integer, Part)

//Add items to the parts dictionary
For Each part As Part In cadPartsArray
  cadParts.Add(part.PartNumber,part)
Next

//Check if a part exists
Dim partNumber As Integer = 12345
If cadParts.ContainsKey(partNumber) ...

//Remove a part
cadParts.Remove(partNumber)

//Go through the remaining values
For Each part As Part In cadParts.Values ...

编辑:

1)是的,如果你的密钥(这里是部件号)是一个字符串,那么将使用一个字典(Of String,...)。

2)我假设你有一个名为Part的类,其中包含一些关于部件的信息。如果您只有部件号而没有其他信息,那么您可以改为创建一个Hashset。它基本上与字典相同,但是使用这种结构,值也是你的关键。您可以创建一个这样的哈希集:

Dim cadParts As New Hashset(Of String)

我不会通过代码示例,因为它非常接近Dictionary。 ContainsKey变为Contains,Add只接受一个参数(这里是你的部件号)。

3)是的,循环遍历它们并将它们添加到hashset。

答案 1 :(得分:2)

如果部件号是唯一的(在您要搜索的值中不重复),则可以使用排序字典。然后删除重复项并使用剩余项目。

要进行比较,您可以按如下方式使用部件号:

if(dictionary.ContainsKey(partNumber))
    dictionary.Remove(partNumber)
end if

答案 2 :(得分:2)

鉴于一次只能看到一定数量的数据网格行,在OnPaint方法中实现一些代码可能会更快(我在这里有点生疏,所以如果不是那么道歉对于检查零件信息数组的每一行,并在每一行变得可见时设置每一行的背景颜色,甚至可能将每一行标记为已经处理,因此不需要重复操作。这里可能会有一次初始性能提升,而不是一次处理所有行。

没有实际意义;但从以往的经验来看,这听起来像是在与AutoDESK Inventor文件接口?

答案 3 :(得分:1)

另一种解决方案可能是实现IComparable(Of T)接口

这需要您构建一个可用于两种情况的类。

Public Class Item
    Implements IComparable(Of Item)

    Private _Description As String
    Public Property Description() As String
        Get
            Return _Description
        End Get
        Set(ByVal value As String)
            _Description = value
        End Set
    End Property

    Private _PartNo As Integer
    Public Property PartNo() As Integer
        Get
            Return _PartNo
        End Get
        Set(ByVal value As Integer)
            _PartNo = value
        End Set
    End Property

    Public Function CompareTo(ByVal other As Item) As Integer Implements System.IComparable(Of Item).CompareTo
        ' Your rules for comparing content for objects
        If other.PartNo <> Me.PartNo Then Return 1
        If other.Description <> Me.Description Then Return 1

        ' Return 0 if the object are the same
        Return 0
    End Function
End Class

这是一个与上层实现一起使用的小测试。

    Dim item As New Item
    item.Description = "Desc"
    item.PartNo = 34

    Dim item2 As New Item
    item2.Description = "Desc"
    item2.PartNo = 35

    Dim item3 As New Item
    item3.Description = "Desc"
    item3.PartNo = 36

    Dim listFromDatabase As New Generic.List(Of Item)
    listFromDatabase.Add(item)
    listFromDatabase.Add(item2)

    If listFromDatabase.Contains(item2) Then
        MessageBox.Show("item2 was found in list")
    End If

    If Not listFromDatabase.Contains(item3) Then
        MessageBox.Show("item3 was NOT found in list")
    End If

希望它有点帮助, - 丹