Jump to content

Compare multiple arrays


Recommended Posts

Hi,

As part of an project for work im using AutoIT v3 to compare an set of user groups in AD to make template accounts.

I've made it up to the point where it connects to AD and gets the groups for multiple users and places in an nested array.

Does anyone know how to compare the values in multiple arrays (> 2) and return values that exist in all of the arrays?

e.g.

$array1 = {1 ,2 ,3 ,4 ,A ,B ,C ,D}
$array2 = {1 ,2 ,3 ,4 ,E ,F ,G ,H}
$array3 = {1 ,2 ,3 ,4 ,I ,J ,K ,L}
$array4 = {1 ,2 ,3 ,4 ,M ,N ,O ,P}

Should return

$retarray = {1 ,2 ,3 ,4 }
Link to comment
Share on other sites

#include <Array.au3>

Local $array1 = StringSplit("1234ABCD", "", 2)
Local $array2 = StringSplit("123456EAGH", "", 2)
Local $array3 = StringSplit("12345678IJAK", "", 2)
Local $array4 = StringSplit("1234567890LABNO", "", 2)

Local $avArrays[4] = [$array1, $array2, $array3, $array4]
Local $avResult

For $i = 1 To UBound($avArrays)-1
    $avResult = _ArraysGetRepeatElem($avArrays[0], $avArrays[$i])
Next

_ArrayDisplay($avResult)


Func _ArraysGetRepeatElem(ByRef $avArr1, ByRef $avArr2)
    Local $iArrays, $iUB1, $iUB2, $avRet[1]
    Local $i, $j, $k = 0

    If UBound($avArr1, 0) <> 1 Or UBound($avArr2, 0) <> 1 Then Return SetError(1, 0, 0)

    $iUB1 = UBound($avArr1)
    $iUB2 = UBound($avArr2)

    If $iUB1 < $iUB2 Then
        ReDim $avRet[$iUB2+1]

        For $i = 0 To $iUB1-1
            For $j = 0 To $iUB2-1
                If $avArr1[$i] == $avArr2[$j] Then
                    $avRet[$k] = $avArr1[$i]
                    $k += 1
                EndIf
            Next
        Next
    Else
        ReDim $avRet[$iUB1+1]

        For $i = 0 To $iUB2-1
            For $j = 0 To $iUB1-1
                If $avArr2[$i] == $avArr1[$j] Then
                    $avRet[$k] = $avArr2[$i]
                    $k += 1
                EndIf
            Next
        Next
    EndIf

    If $k = 0 Then Return 0
    ReDim $avRet[$k]
    Return $avRet
EndFunc

Link to comment
Share on other sites

There is a "subtle" issue. If one array contains the same value multiple times, and the other array contains this value, the value will be added multiple times as well. This probably isn't what you want. If so, you need to check if $avRet does not contain the value you're about to add.

Edit: What I was referring to:

#include <Array.au3>

Local $array1 = StringSplit("1234AABCD", "", 2)
Local $array2 = StringSplit("123456EAGH", "", 2)
Local $array3 = StringSplit("12345678IJAK", "", 2)
Local $array4 = StringSplit("1234567890LABNO", "", 2)

Local $avArrays[4] = [$array1, $array2, $array3, $array4]
Local $avResult

For $i = 1 To UBound($avArrays)-1
    $avResult = _ArraysGetRepeatElem($avArrays[0], $avArrays[$i])
Next

_ArrayDisplay($avResult)


Func _ArraysGetRepeatElem(ByRef $avArr1, ByRef $avArr2)
    Local $iArrays, $iUB1, $iUB2, $avRet[1]
    Local $i, $j, $k = 0

    If UBound($avArr1, 0) <> 1 Or UBound($avArr2, 0) <> 1 Then Return SetError(1, 0, 0)

    $iUB1 = UBound($avArr1)
    $iUB2 = UBound($avArr2)

    If $iUB1 < $iUB2 Then
        ReDim $avRet[$iUB2+1]

        For $i = 0 To $iUB1-1
            For $j = 0 To $iUB2-1
                If $avArr1[$i] == $avArr2[$j] And _ArraySearch($avRet, $avArr1[$i]) = -1 Then
                    $avRet[$k] = $avArr1[$i]
                    $k += 1
                EndIf
            Next
        Next
    Else
        ReDim $avRet[$iUB1+1]

        For $i = 0 To $iUB2-1
            For $j = 0 To $iUB1-1
                If $avArr2[$i] == $avArr1[$j] And _ArraySearch($avRet, $avArr2[$i]) = -1 Then
                    $avRet[$k] = $avArr2[$i]
                    $k += 1
                EndIf
            Next
        Next
    EndIf

    If $k = 0 Then Return 0
    ReDim $avRet[$k]
    Return $avRet
EndFunc
Edited by Authenticity
Link to comment
Share on other sites

A new improved modified Authenticity's version.

#include <Array.au3>

Local $array1 = StringSplit("1234ABCD", "", 2)
Local $array2 = StringSplit("12345678IJAK", "", 2)
Local $array3 = StringSplit("123456EAGH", "", 2)
Local $array4 = StringSplit("1234567890LABNO", "", 2)

Local $avArrays[4] = [$array1, $array2, $array3, $array4]
Local $avResult

$avResult = $avArrays[0]
For $i = 1 To UBound($avArrays) - 1
    $avResult = _ArraysGetRepeatElem($avResult, $avArrays[$i])
Next

_ArrayDisplay($avResult)


Func _ArraysGetRepeatElem(ByRef $avArr1, ByRef $avArr2)
    Local $iArrays, $iUB1, $iUB2
    Local $i, $j, $k = 0

    If UBound($avArr1, 0) <> 1 Or UBound($avArr2, 0) <> 1 Then Return SetError(1, 0, 0)

    $iUB1 = UBound($avArr1)
    $iUB2 = UBound($avArr2)
    Local $avRet[$iUB1 + 1]
    If $iUB1 < $iUB2 Then ReDim $avRet[$iUB2 + 1]

    For $i = 0 To $iUB1 - 1
        For $j = 0 To $iUB2 - 1
            If $avArr1[$i] == $avArr2[$j] Then
                $avRet[$k] = $avArr1[$i]
                $k += 1
            EndIf
        Next
    Next
    If $k = 0 Then Return 0
    ReDim $avRet[$k]
    Return $avRet
EndFunc ;==>_ArraysGetRepeatElem

And here is another version.

#include <Array.au3>

;Modified from: http://www.autoitscript.com/forum/index.php?showtopic=115759&view=findpost&p=808372
Local $array1 = StringSplit("1234ABCD", "", 2)
Local $array2 = StringSplit("12345678IJAK", "", 2)
Local $array3 = StringSplit("123456EAGH", "", 2)
Local $array4 = StringSplit("1234567890LABNO", "", 2)

Local $avArrays[4] = [$array1, $array2, $array3, $array4]

Local $aArr = _ArraysGetRepeatElem($avArrays)

_ArrayDisplay($aArr)

; Parameter $aArrays is an array of the arrays to be compared.
; Returns an array of the matching elements that repeat in every array.
Func _ArraysGetRepeatElem(ByRef $aArrays)
    Local $aResult = $aArrays[0]
    For $i = 1 To UBound($aArrays) - 1
        Local $iUB1, $iUB2, $i, $j, $k = 0, $aArr1
        If UBound($aResult, 0) <> 1 Or UBound($aArrays[$i], 0) <> 1 Then Return SetError(1, 0, 0)
        $iUB1 = UBound($aResult)
        $iUB2 = UBound($aArrays[$i])
        $aArr1 = $aArrays[$i]
        Local $avRet[$iUB1 + 1]
        If $iUB1 < $iUB2 Then Local $avRet[$iUB2 + 1]
        For $h = 0 To $iUB1 - 1
            For $j = 0 To $iUB2 - 1
                If $aResult[$h] == $aArr1[$j] Then
                    $avRet[$k] = $aResult[$h]
                    $k += 1
                EndIf
            Next
        Next
        If $k = 0 Then Return 0
        ReDim $avRet[$k]
        $aResult = $avRet
    Next
    Return $aResult
EndFunc ;==>_ArraysGetRepeatElem

Edit: Added Other version

Edited by Malkey
Link to comment
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now
 Share

  • Recently Browsing   0 members

    • No registered users viewing this page.
×
×
  • Create New...