vb@rchiv
VB Classic
VB.NET
ADO.NET
VBA
C#
Blitzschnelles Erstellen von grafischen Diagrammen!  
 vb@rchiv Quick-Search: Suche startenErweiterte Suche starten   Impressum  | Datenschutz  | vb@rchiv CD Vol.6  | Shop Copyright ©2000-2024
 
zurück
Rubrik: Variablen/Strings · Array/ArrayList   |   VB-Versionen: VB200809.02.09
Vergleich von zwei Arrays

Erweiterung zur Prüfung, ob zwei Arrays identisch deklariert sind und ihre Elemente den gleichen Inhalt besitzen.

Autor:   Manfred BohnBewertung:     [ Jetzt bewerten ]Views:  19.703 
ohne HomepageSystem:  Win2k, WinXP, Win7, Win8, Win10, Win11kein Beispielprojekt 

Die Überprüfung, ob zwei System.Arrays gleich sind, ist in Visual Basic relativ einfach, falls die Elemente die IComparable-Schnittstelle implementiert haben. Das trifft z.B. auf alle sog. Primitiven Typen zu.

Man überprüft zunächst die Rahmenkonstruktion der Arrays (Nothing, Type, Rank, Bounds). Die Nothing-Prüfung ist erforderlich, weil Array-Variable Referenztypen sind, auch wenn die Elemente aus einem Werttyp bestehen.

Findet man beim Vergleich eine identische Rahmenkonstruktion, überträgt man die Array-Elemente jeweils in ein eindimensionales Object-Array, um die Rank-spezifische Indizierung loszuwerden (per Linq / ToArray-Erweiterung). Der Typ der einzelnen Array-Elemente bleibt dabei erhalten, es ändert sich nur die Array-Variable.

Durch eine einfache Schleife können die korrespondierenden Array-Elemente miteinander verglichen werden (Nothing, Type, Content). Die Nothing- und Type-Checks sind erforderlich, weil Arrays Element-Referenzen auf alle möglichen Strukturen, Objekte und auch auf Nothing enthalten können.

Die Erweiterungen 'IsEqual' heften sich an Arrays, deren Array-Variablen-Deklaration signalisiert, dass die Comparable-Schnittstelle implementiert ist. Sie erlauben als Parameter nur Arrays, die die gleiche Zahl von Dimensionen aufweisen (1-3).

Die Erweiterung 'Equality' heftet sich an alles, was nach einem System.Array aussieht. Als Parameter wird ebenfalls jedes System.Array zur Entwicklungszeit akzeptiert. Falls die Array-Elemente die IComparable-Schnittstelle nicht implementiert haben, wird eine Ausnahme ausgelöst.

Einige Beispiele:

Module modArrayEqual_Exempl
  Public Sub IsArrayEqual_Exempl()
    Dim i1(), i2() As Short
 
    If i1.IsEqual(i2) Then Stop
    ' ---> Stop erreicht, weil beide Nothing sind
 
    Dim i3(0) As Short
    If Not i1.IsEqual(i3) Then Stop
    ' ---> Stop erreicht, weil 'i3' nicht nothing ist
 
    Dim i4(0) As Integer
    If Not i3.Equality(i4) Then Stop
    ' ---> Stop erreicht, weil unterschiedliche Array-Typen vorliegen
 
    Dim i5(0, 0) As Short
    If Not i3.Equality(i5) Then Stop
    ' ---> Stop erreicht, weil unterschiedliche Dimensionen vorliegen
 
    Dim i6(0, 1) As Short
    If Not i5.IsEqual(i6) Then Stop
    ' ---> Stop erreicht, weil unterschiedliche Grenzen vorliegen
 
    Dim i7(0, 1) As Short
    i7(0, 0) = 1
    If Not i6.IsEqual(i7) Then Stop
    ' ---> Stop erreicht, weil unterschiedliche Arrayinhalte vorliegen
 
    Dim t1 As String = "Test1", t2 As String = "TEST1"
    If Not t1.ToCharArray.IsEqual(t2.ToCharArray) Then Stop
    ' ---> Stop erreicht, weil case-sensitiver Vergleich vorgenommen wird
 
    Dim c1(0) As Object, c2(0) As Object
    c1(0) = 1% : c2(0) = 1.0#
    If Not c1.Equality(c2) Then Stop
    ' ---> Stop erreicht, weil Elementtyp Integer <> Double ist
 
    Dim oa1(10), oa2(10) As Object
    oa1(0) = CShort(0)
    oa1(1) = 1 : oa1(2) = 2.0! : oa1(3) = 3.0#
    oa1(4) = "x"c
    oa1(5) = CByte(5) : oa1(6) = CULng(6)
    oa1(7) = 1.0#
    For i As Integer = 0 To 10 : oa2(i) = oa1(i) : Next i
    oa2(7) = CDbl(oa1(7)) + (1000.0# * Double.Epsilon)
    If oa1.Equality(oa2) Then Stop
    ' ---> Stop wird erreicht, weil beide Arrays als gleich gelten
    ' Der Unterschied ist im Datentyp nicht darstellbar
 
    Dim p1(5) As cPersonalDaten
    Dim p2(5) As cPersonalDaten
    p1(0) = New cPersonalDaten("Maier", "Hans", "Schlosser")
    p1(1) = New cPersonalDaten("Müller", "Georg", "Pfoertner")
    p1(2) = New cPersonalDaten("Schneider", "Eduard", "Maschinist")
    p1(4) = New cPersonalDaten("Gerber", "Harald", "Buchhalter")
 
    For i As Integer = 0 To p1.Length - 1
      If Not p1(i) Is Nothing Then
        With p1(i)
          '  echte Kopien der Instanzen durch Konstruktor erstellen
          p2(i) = New cPersonalDaten(._Name, ._Vorname, ._Position)
        End With
      End If
    Next i
 
    If p1.IsEqual(p2) Then Stop
    ' ---> Stop wird erreicht, weil alle Elemente identisch sind,
    ' auch die Nothing-Elemente !!!
  End Sub
  ''' <summary>Demoklasse, implementiert IComparable für
  ''' Vergleich von Instanzen (nicht zum Sortieren geeignet!!)
  ''' </summary>
  Private Class cPersonalDaten
    Implements IComparable
 
    ' öffentliche Membervariablen
    Public _Vorname As String
    Public _Name As String
    Public _Position As String
 
    ''' <summary>Demoklasse, implementiert IComparable für
    ''' Vergleich von Instanzen (nicht zum Sortieren geeignet!!)
    ''' </summary>
    Public Sub New(ByVal name As String, _
      ByVal vorname As String, _
      ByVal position As String)
 
      _Name = name
      _Vorname = vorname
      _Position = position
    End Sub
 
    Public Function CompareTo(ByVal obj As Object) As Integer _
      Implements System.IComparable.CompareTo
      If Me.Equals(obj) Then Return 0
      Dim v As cPersonalDaten = CType(obj, cPersonalDaten)
      With v
        If _Vorname <> ._Vorname Then Return -1
        If _Name <> ._Name Then Return -1
        If _Position <> ._Position Then Return -1
      End With
      Return 0
    End Function
  End Class
End Module
Option Strict On
Option Explicit On
Option Infer Off
 
Imports System
Imports System.Math
Imports System.Linq.Enumerable
 
Module modIsArrayEqual
  ''' <summary>
  ''' Prüfung der Gleichheit von zwei System.Arrays
  ''' Vergleich: Rank, Bounds, Type, Content (per IComparable)
  ''' </summary>
  ''' <param name="arr1">1. zu vergleichendes Array</param>
  ''' <param name="arr2">2. zu vergleichendes Array</param>
  ''' <returns>true falls identisch, sonst false</returns>
  <System.Runtime.CompilerServices.Extension()> _
  Public Function IsEqual(Of T As IComparable) _
    (ByVal arr1 As T(), ByVal arr2 As T()) As Boolean
    Return Equality(arr1, arr2)
  End Function
  ''' <summary>
  ''' Prüfung der Gleichheit von zwei System.Arrays
  ''' Vergleich: Rank, Bounds, Type, Content (per IComparable)
  ''' </summary>
  ''' <param name="arr1">1. zu vergleichendes Array</param>
 ''' <param name="arr2">2. zu vergleichendes Array</param>
  ''' <returns>true falls identisch, sonst false</returns>
  <System.Runtime.CompilerServices.Extension()> _
  Public Function IsEqual(Of T As IComparable) _
    (ByVal arr1 As T(,), ByVal arr2 As T(,)) As Boolean
    Return Equality(arr1, arr2)
  End Function
  ''' <summary>Prüfung der Gleichheit von zwei System.Arrays
  ''' Vergleich: Rank, Bounds, Type, Content (per IComparable)
  ''' </summary>
  ''' <param name="arr1">1. zu vergleichendes Array</param>
  ''' <param name="arr2">2. zu vergleichendes Array</param>
  ''' <returns>true falls identisch, sonst false</returns>
  <System.Runtime.CompilerServices.Extension()> _
  Public Function IsEqual(Of T As IComparable) _
    (ByVal arr1 As T(,,), ByVal arr2 As T(,,)) As Boolean
    Return Equality(arr1, arr2)
  End Function
  ''' <summary>Prüfung der Gleichheit von zwei System.Arrays
  ''' Vergleich: Rank, Bounds, Type, Content (per IComparable)
  ''' </summary>
  ''' <param name="arr1">1. zu vergleichendes Array</param>
  ''' <param name="arr2">2. zu vergleichendes Array</param>
  ''' <returns>true falls identisch, sonst false</returns>
  <System.Runtime.CompilerServices.Extension()> _
  Public Function Equality _
    (ByVal arr1 As System.Array, ByVal arr2 As System.Array) As Boolean
 
    Dim iarr1(), iarr2() As Object
    Dim typ1, typ2 As System.Type
    Dim el1, el2 As IComparable
 
    ' Nothing = Nothing
    If arr1 Is Nothing And arr2 Is Nothing Then Return True
 
    ' Ein einzelner Nothing-Parameter führt immer zu 'false'
    If arr1 Is Nothing Or arr2 Is Nothing Then Return False
 
    ' Identisches Objekt?
    If arr1.Equals(arr2) Then Return True
 
    ' Datentyp und Rank der Arrays vergleichen?
    If Not arr1.GetType.Equals(arr2.GetType) Then Return False
 
    ' Index-Obergrenzen vergleichen
    For i As Integer = 0 To arr1.Rank - 1
      If arr1.GetUpperBound(i) <> arr2.GetUpperBound(i) Then Return False
    Next i
 
    ' Array-Elemente per Linq in 
    ' eindimensionale Arrays eintragen
    iarr1 = (From x In arr1).ToArray
    iarr2 = (From x In arr2).ToArray
 
    For i As Integer = 0 To iarr1.Length - 1
      ' Vergleich der Array-Elemente (IComparable)
      If iarr1(i) Is Nothing Or iarr2(i) Is Nothing Then
        ' Vergleich von Nothing-Elementen
        If iarr1(i) Is Nothing And Not iarr2(i) Is Nothing Then Return False
        If Not iarr1(i) Is Nothing And iarr2(i) Is Nothing Then Return False
      Else
        ' Typ der korrespondierenden Array-Elemente
        typ1 = iarr1(i).GetType : typ2 = iarr2(i).GetType
 
        ' Gleicher Typ?
        If Not typ1.Equals(typ2) Then Return False
 
        ' Gleicher Inhalt?
        el1 = CType(iarr1(i), IComparable)
        el2 = CType(iarr2(i), IComparable)
        If el1.CompareTo(el2) <> 0 Then Return False
      End If
    Next i
    Return True
  End Function
End Module

Dieser Tipp wurde bereits 19.703 mal aufgerufen.

Voriger Tipp   |   Zufälliger Tipp   |   Nächster Tipp

Über diesen Tipp im Forum diskutieren
Haben Sie Fragen oder Anregungen zu diesem Tipp, können Sie gerne mit anderen darüber in unserem Forum diskutieren.

Neue Diskussion eröffnen

nach obenzurück


Anzeige

Kauftipp Unser Dauerbrenner!Diesen und auch alle anderen Tipps & Tricks finden Sie auch auf unserer aktuellen vb@rchiv  Vol.6

Ein absolutes Muss - Geballtes Wissen aus mehr als 8 Jahren vb@rchiv!
- nahezu alle Tipps & Tricks und Workshops mit Beispielprojekten
- Symbol-Galerie mit mehr als 3.200 Icons im modernen Look
Weitere Infos - 4 Entwickler-Vollversionen (u.a. sevFTP für .NET), Online-Update-Funktion u.v.m.
 
   

Druckansicht Druckansicht Copyright ©2000-2024 vb@rchiv Dieter Otter
Alle Rechte vorbehalten.
Microsoft, Windows und Visual Basic sind entweder eingetragene Marken oder Marken der Microsoft Corporation in den USA und/oder anderen Ländern. Weitere auf dieser Homepage aufgeführten Produkt- und Firmennamen können geschützte Marken ihrer jeweiligen Inhaber sein.

Diese Seiten wurden optimiert für eine Bildschirmauflösung von mind. 1280x1024 Pixel