Jump to content
Sign in to follow this  
lostangel556

Compare multiple arrays

Recommended Posts

lostangel556

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 }

Share this post


Link to post
Share on other sites
Authenticity

#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

Share this post


Link to post
Share on other sites
lostangel556

You Legend.

I've been racking my brain for hours on this an it works flawlessly :mellow:

Share this post


Link to post
Share on other sites
Authenticity

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

Share this post


Link to post
Share on other sites
lostangel556

The above works fine as im comparing arrays compiled of Active Directory groups that an user is member of so unable to have duplicate groupds on the persons account.

Share this post


Link to post
Share on other sites
Malkey

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

Share this post


Link to post
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
Sign in to follow this  

×

Important Information

We have placed cookies on your device to help make this website better. You can adjust your cookie settings, otherwise we'll assume you're okay to continue.