VBScript - Compare two arrays of strings and remove intersection of arrays

I have a file, x.txt, that are read into Array1 and the array is then sorted.

I perform a search against an LDAP directory and populate Array2 and the array is then sorted.

I want to compare Array1 to Array2 and remove all instances of strings which occur in both arrays and place the results in a third array which I will then sort.
LVL 16
Darrell PorterEnterprise Business Process ArchitectAsked:
Who is Participating?

[Product update] Infrastructure Analysis Tool is now available with Business Accounts.Learn More

x
I wear a lot of hats...

"The solutions and answers provided on Experts Exchange have been extremely helpful to me over the last few years. I wear a lot of hats - Developer, Database Administrator, Help Desk, etc., so I know a lot of things but not a lot about one thing. Experts Exchange gives me answers from people who do know a lot about one thing, in a easy to use platform." -Todd S.

Jeff DarlingDeveloper AnalystCommented:
arrSample = Array("red", "white", "blue", "black", "green","orange","zoob")
arrAD = Array("purple","red", "white", "blue", "green")



arrSample = sortArr(arrSample)
arrOut1 = Unmatched(arrSample,arrAD)
arrOut2 = Unmatched(arrAD,arrSample)
arrout3 = sortArr(combined(arrout1,arrout2))


WScript.Echo vbCrLf & "Results"
WScript.Echo "-------------------"

For Each intNumber In arrOut1
  WScript.Echo intNumber
Next
For Each intNumber In arrOut2
  WScript.Echo intNumber
Next

WScript.Echo vbCrLf & "Results sorted"
WScript.Echo "-------------------"
For Each intNumber In arrOut3
  WScript.Echo intNumber
Next



Public Function combined(arr1,arr2)

Dim arrOut()
ReDim arrOut(UBound(arr1)+UBound(arr2)+1)

k=0
For i = 0 To UBound(arr1)
arrOut(k) = arr1(i)
k=k+1
Next

For i = 0 To UBound(arr2)
arrOut(k) = arr2(i)
k=k+1
Next

combined = arrOut

End Function


Public Function Unmatched(arr1,arr2)

Dim arr3()

k=0
For i = 0 To UBound(arr1)
bFound = False
For j = 0 To ubound(arr2)
  If arr1(i) = arr2(j) Then
   bFound = True
  End If
Next
If Not bFound Then
  k=k+1
End If
Next

ReDim arr3(k - 1)

k=0
For i = 0 To UBound(arr1)
bFound = False
For j = 0 To ubound(arr2)
  If arr1(i) = arr2(j) Then
   bFound = True
  End If
Next
If Not bFound Then
  arr3(k) = arr1(i)
  k=k+1
End If
Next

Unmatched = arr3

End Function



Public Function sortArr(arrSample)

For i = LBound(arrSample) to UBound(arrSample)
  For j = LBound(arrSample) to UBound(arrSample)
    If j <> UBound(arrSample) Then
      If arrSample(j) > arrSample(j + 1) Then
         TempValue = arrSample(j + 1)
         arrSample(j + 1) = arrSample(j)
         arrSample(j) = TempValue
      End If
    End If
  Next
Next

sortArr = arrSample

End Function

Open in new window

0

Experts Exchange Solution brought to you by

Your issues matter to us.

Facing a tech roadblock? Get the help and guidance you need from experienced professionals who care. Ask your question anytime, anywhere, with no hassle.

Start your 7-day free trial
Bill PrewIT / Software Engineering ConsultantCommented:
I think I'd do this using Dictionary objects, would be simpler to code and work with.  But before I write that up I wanted to see if there was a reason you required arrays?

~bp
0
Bill PrewIT / Software Engineering ConsultantCommented:
Here's an example of a dictionary based approach.

' Test data
arrTXT = Array("red", "white", "blue", "black", "green","orange","zoob")
arrAD = Array("purple","red", "white", "blue", "green")

' Define dictionaries for matching
Set objDict1 = CreateObject("Scripting.Dictionary")
objDict1.CompareMode = vbTextCompare
Set objDict2 = CreateObject("Scripting.Dictionary")
objDict2.CompareMode = vbTextCompare
Set objDict3 = CreateObject("Scripting.Dictionary")
objDict3.CompareMode = vbTextCompare

' Load first set of data into dict 1
For Each strTXT in arrTXT
   objDict1.Add strTXT, 0
Next

' Load second set of data into dict 2
' duplicate with dict 1 go to dict 3, and delete entry from dict 1
For Each strAD in arrAD
   If objDict1.Exists(strAD) Then
      objDict3.Add strAD, 0
      objDict1.Remove(strAD)
   Else
      objDict2.Add strAD, 0
   End If
Next

' Display results
Wscript.Echo "----- objDict1 -----"
For Each strKey in objDict1
   Wscript.Echo strKey
Next
Wscript.Echo "----- objDict2 -----"
For Each strKey in objDict2
   Wscript.Echo strKey
Next
Wscript.Echo "----- objDict3 -----"
For Each strKey in objDict3
   Wscript.Echo strKey
Next

Open in new window

~bp
0
Why Diversity in Tech Matters

Kesha Williams, certified professional and software developer, explores the imbalance of diversity in the world of technology -- especially when it comes to hiring women. She showcases ways she's making a difference through the Colors of STEM program.

Jeff DarlingDeveloper AnalystCommented:
Reasons that Dictionary may be better than using an array.

1. Easier to add new items to list
2. Built in sort function
3. Built in exists function
4. less coding
0
Bill PrewIT / Software Engineering ConsultantCommented:
Unfortunately, there actually isn't any sort capability built into Dictionaries.  They are just basically associative arrays.

There are examples on the net though of sort routines for a Dictionary.  In this case I wasn't sure if it was actually needed, or just being done to assist the array matching process.

If the result needs to be ordered then we could certainly add a sort to the dictionary, although the amount of code that it takes to do that is actually quite large, so I'd only do it if it was truly needed.

I think Dictionaries are also a bit more friendly in terms of being a "key, value" pair.  Each key in the dictionary has a data element associated with it (which can actually be any other object so you can associate almost anything with a key).  You could try and emulate this with multi dimension arrays, but it gets ugly fast.

One last benefit to add is the "auto sizing" nature of a Dictionary.  It's very easy to add and delete from it without having to re-dimension it, etc.

~bp
0
Darrell PorterEnterprise Business Process ArchitectAuthor Commented:
The data is already in arrays (loaded from LDAP queries run against Active Directory).

I built an array-based bubble sort (which is surprisingly quick, considering) so I don't need to add another sorting function.

The array is only sorted to ensure the resultant dataset is executed on a per-office basis, based on the computername three- or five-letter prefix which denotes city (3-letter) or state and city (5-letter) prefix.

I have no objection to using dictionaries to perform the necessary function - I can always convert an array to a dictionary and dictionary keys/items to an array.

In the event anyone is interested, the end result of this project is to have a solution, based on VBScript, which iterates through all Windows XP, Windows Vista, Windows 7, and Windows 8 computers and sets the local admin password to a unique value for each workstation in such a way that a database is not required to store the password yet is trivial for workstation/end-user support staff to know the local admin password without having to look it up (in most cases).

Thank you all for your assistance.  I will be looking at these responses more in-depth this afternoon.
0
Bill PrewIT / Software Engineering ConsultantCommented:
Okay, if you really want to work with the arrays that's fine, here's an approach to that.  Rather than building new versions of the TXT and AD arrays, it removes duplicates from the existing arrays.

' Test data
arrTXT = Array("red", "white", "blue", "black", "green","orange","zoob")
arrAD = Array("purple","red", "white", "blue", "green")

' Array to add dupes to
Dim arrDupes()
intDupes = -1

' Look at each entry in the TXT array
intTXT = LBound(arrTXT)
Do While intTXT <= UBound(arrTXT)

   ' See if this entry is in the AD array
   intAD = -1
   For i = LBound(arrAD) To UBound(arrAD)
      If LCase(arrAD(i)) = LCase(arrTXT(intTXT)) Then
         intAD = i
         Exit For
      End If
   Next

   ' Found a dupe?
   If intAD > -1 Then

      ' Add to DUPES array
      intDupes = intDupes + 1
      ReDim Preserve arrDupes(intDupes)
      arrDupes(intDupes) = arrTXT(intTXT)

      ' Remove from TXT array
      For i = intTXT To UBound(arrTXT) - 1
         arrTXT(i) = arrTXT(i + 1)
      Next
      Redim Preserve arrTXT(UBound(arrTXT) - 1)

      ' Remove from AD array
      For i = intAD To UBound(arrAD) - 1
         arrAD(i) = arrAD(i + 1)
      Next
      Redim Preserve arrAD(UBound(arrAD) - 1)

   Else

      ' Move on to next element in TXT array
      intTXT = intTXT + 1

   End If

Loop

' Display results
Wscript.Echo "----- arrTXT -----"
For Each strKey in arrTXT
   Wscript.Echo strKey
Next
Wscript.Echo "----- arrAD -----"
For Each strKey in arrAD
   Wscript.Echo strKey
Next
Wscript.Echo "----- arrDupes -----"
For Each strKey in arrDupes
   Wscript.Echo strKey
Next

Open in new window

~bp
0
Darrell PorterEnterprise Business Process ArchitectAuthor Commented:
Bill and Jeff,

Thank you both for your assistance with this issue,

WT
0
It's more than this solution.Get answers and train to solve all your tech problems - anytime, anywhere.Try it for free Edge Out The Competitionfor your dream job with proven skills and certifications.Get started today Stand Outas the employee with proven skills.Start learning today for free Move Your Career Forwardwith certification training in the latest technologies.Start your trial today
VB Script

From novice to tech pro — start learning today.