2

I need to create third array from difference of two arrays, I simply can not get the logic of this

The correct third array v3 would be (from the code below) v3 = (Carol, Ted, Thor, Freya)

Thanks

Sub MatchArrays()
Dim v1, v2, v3
Dim i As Long, j As Long

v1 = Array("Bob", "Carol", "Ted", "Alice", "Thor", "Freya")
v2 = Array("Bob", "Carol")

ReDim v3(LBound(v1) To Abs(UBound(v1) - UBound(v2)))

For i = LBound(v1) To UBound(v1)
   For j = LBound(v2) To UBound(v2)
     If InStr(1, v1(i), v2(j)) Then
       v3(i) = v1(i)
       Exit For
     End If
   Next j
  MsgBox v3(i)
Next i
End Sub
Community
  • 1
  • 1
xyz
  • 2,253
  • 10
  • 46
  • 68

3 Answers3

3

This one uses Collections and the fact that adding a duplicated key raises an error. It doesn't matter whether v1 or v2 is the subset:

Sub test()
Dim v1 As Variant, v2 As Variant, v3 As Variant
Dim coll As Collection
Dim i As Long

'Assumes 0-based Variants
v1 = Array("Bob", "Carol", "Ted", "Alice", "Thor", "Freya")
v2 = Array("Bob", "Carol")
ReDim v3(LBound(v1) To Abs(UBound(v2) - UBound(v1)) - 1)

Set coll = New Collection
For i = LBound(v1) To UBound(v1)
    coll.Add v1(i), v1(i)
Next i
For i = LBound(v2) To UBound(v2)
    On Error Resume Next
    coll.Add v2(i), v2(i)
    If Err.Number <> 0 Then
        coll.Remove v2(i)
    End If
    On Error GoTo 0
Next i
For i = LBound(v3) To UBound(v3)
    v3(i) = coll(i + 1) 'Collections are 1-based
    Debug.Print v3(i)
Next i
End Sub
Doug Glancy
  • 27,214
  • 6
  • 67
  • 115
  • I chose this as it makes it so I do not have to know which is the subset, thank you – xyz Nov 09 '15 at 03:14
2

Try this:

Sub Test()

Dim v1, v2, v3
Dim i As Long, j As Long
Dim str As String

v1 = Array("Bob", "Carol", "Ted", "Alice", "Thor", "Freya")
v2 = Array("Bob", "Carol")

ReDim v3(LBound(v1) To Abs(UBound(v1) - UBound(v2)))

For i = LBound(v1) To UBound(v1) 'Assuming, that v2 is always the subset of v1

str = v1(i)

If Not IsInArray(str, v2) Then

v3(j) = v1(i)
MsgBox v3(j)
j = j + 1

End If

Next

End Sub

Function IsInArray(stringToBeFound As String, arr As Variant) As Boolean
IsInArray = (UBound(Filter(arr, stringToBeFound)) > -1)
End Function
MGP
  • 2,480
  • 1
  • 18
  • 31
  • 1
    I had a similar problem the other day, and stumbled upon this [article](http://stackoverflow.com/questions/11109832/how-to-find-if-an-array-contains-a-string) – MGP Nov 09 '15 at 02:09
  • 1
    Worth noting that Filter matches on substrings: `Join(Filter(Array("Timothy","Tim"),"Tim"),",")` ->> "Timothy,Tim" – Tim Williams Nov 09 '15 at 17:12
  • This is true! Thanks for pointing this out! One would probably have to use `Len`somewhere to check, that the `stringToBeFound` and the found string have the same length. – MGP Nov 10 '15 at 13:28
1

I believe this is what you want:

Sub MatchArrays()
Dim v1, v2, v3
Dim i As Long, j As Long
Dim here As Boolean
Dim f As Long
v1 = Array("Bob", "Carol", "Ted", "Alice", "Thor", "Freya")
v2 = Array("Bob", "Carol")
f = LBound(v1)
ReDim v3(LBound(v1) To Abs(UBound(v1) - UBound(v2)))

For i = LBound(v1) To UBound(v1)
    here = False
    For j = LBound(v2) To UBound(v2)
        If InStr(1, v1(i), v2(j)) Then
            here = True
            Exit For
        End If
    Next j
    If Not here Then
        v3(f) = v1(i)
        MsgBox v3(f)
        f = f + 1
    End If
Next i
End Sub
Scott Craner
  • 148,073
  • 10
  • 49
  • 81