Jump to content

compare 2 arrays with 3 arrays as a result


Go to solution Solved by iamtheky,

Recommended Posts

Hi

has anyone created a script to compare 2 arrays like this : 

compare the 2 arrays

- the items that are only in array 1 go into a new array

- the items that are only in array 2 go into another new array

- the items that are in both arrays go into another new array

like this : 

Global $Compare1[10] = [1, 3, 5, 6, 7, 8, 9, 10, 11, 12]

Global $Compare2[10] = [1, 2, 3, 4, 5, 6, 8, 10, 12, 13]

$whatsLeftOfCompare1 = [7, 9, 11]

$whatsLeftOfCompare2 = [2, 4, 13]

$whatsInBoth = [1, 3, 5, 6, 8, 10, 12]

I want to use this to compare 2 arrays with Active Directory rights and check which rights users have in comon and which rights they have separatly.

if any anyone has created this before and would like to share it, I would appreciate it very much!

I was searching on the forum but I didn't find anything that looks like this and I'm not really sure how I could achieve this without using like 4 or  5 loops

Edited by colombeen
Link to comment
Share on other sites

  • Solution

#include <Array.au3>

Global $aCompare1[10] = [1, 3, 5, 6, 7, 8, 9, 10, 11, 12]
Global $aCompare2[10] = [1, 2, 3, 4, 5, 6, 8, 10, 12, 13]
Global $aBoth[0]

For $i = ubound($aCompare1) - 1 to 0 step -1
$iMatch = _ArraySearch($aCompare2 , $aCompare1[$i])
If $iMatch <> -1 then
    _ArrayAdd($aBoth , $aCompare1[$i])
    _ArrayDelete($aCompare1 , $i)
    _ArrayDelete($aCompare2, $iMatch)
EndIf
Next

For $i = ubound($aCompare2) - 1 to 0 step -1
$iMatch = _ArraySearch($aCompare1 , $aCompare2[$i])
If $iMatch <> -1 then
    _ArrayAdd($aBoth , $aCompare2[$i])
    _ArrayDelete($aCompare2 , $i)
    _ArrayDelete($aCompare1 , $iMatch)
EndIf
Next

_ArrayDisplay ($aBoth, "In Both")
_ArrayDisplay ($aCompare1, "Only in Compare 1")
_ArrayDisplay ($aCompare2, "Only in Compare 2")

,-. .--. ________ .-. .-. ,---. ,-. .-. .-. .-.
|(| / /\ \ |\ /| |__ __||| | | || .-' | |/ / \ \_/ )/
(_) / /__\ \ |(\ / | )| | | `-' | | `-. | | / __ \ (_)
| | | __ | (_)\/ | (_) | | .-. | | .-' | | \ |__| ) (
| | | | |)| | \ / | | | | | |)| | `--. | |) \ | |
`-' |_| (_) | |\/| | `-' /( (_)/( __.' |((_)-' /(_|
'-' '-' (__) (__) (_) (__)

Link to comment
Share on other sites

Another way (boththose beat me to it!)...

#include <array.au3>

local $Compare1 = [1, 3, 5, 6, 7, 8, 9, 10, 11, 12]
local $Compare2 = [1, 2, 3, 4, 5, 6, 8, 10, 12, 13, 19, '', 'whatever']
local $Common[1]

for $1 = ubound($Compare1) - 1 to 0 step -1
    for $2 = ubound($Compare2) - 1 to 0 step -1
        if $Compare1[$1] = $Compare2[$2] then
            redim $Common[ubound($Common)+1]
            $Common[ubound($Common)-1] = $Compare2[$2]
            _arraydelete($Compare1,$1)
            _arraydelete($Compare2,$2)
            ExitLoop
        EndIf
    Next
next

_arraydisplay($Compare1,'Compare1')
_arraydisplay($Compare2,'Compare2')
_arraydisplay($Common,'Common')

Forum Rules         Procedure for posting code

"I like pigs.  Dogs look up to us.  Cats look down on us.  Pigs treat us as equals."

- Sir Winston Churchill

Link to comment
Share on other sites

So this is without redim, but when you are reading them out to whatever you are doing with the data preface it with:

If $array[$i] <> "" then ....

#include <Array.au3>

Global $aCompare1[10] = [1, 3, 5, 6, 7, 8, 9, 10, 11, 12]
Global $aCompare2[10] = [1, 2, 3, 4, 5, 6, 8, 10, 12, 13]
Global $aBoth[ubound($aCompare1) * 2]

Global $x = 0

For $i = ubound($aCompare1) - 1 to 0 step -1
$iMatch = _ArraySearch($aCompare2 , $aCompare1[$i])
If $iMatch <> -1 then
    $aBoth[$x] = $aCompare1[$i]
    $aCompare1[$i] = ""
    $aCompare2[$iMatch] = ""
    $x += 1
EndIf
Next

For $i = ubound($aCompare2) - 1 to 0 step -1
$iMatch = _ArraySearch($aCompare1 , $aCompare2[$i])
If $iMatch <> -1 then
    $aBoth[$x] = $aCompare2[$i]
    $aCompare2[$i] = ""
    $aCompare1[$iMatch] = ""
    $x += 1
EndIf
Next

_ArrayDisplay ($aCompare1, "Only in Compare 1")
_ArrayDisplay ($aCompare2, "Only in Compare 2")
_ArrayDisplay ($aBoth, "In Both") 

Or someone smrt will come clean up the blanks all fancy like.

Edited by boththose

,-. .--. ________ .-. .-. ,---. ,-. .-. .-. .-.
|(| / /\ \ |\ /| |__ __||| | | || .-' | |/ / \ \_/ )/
(_) / /__\ \ |(\ / | )| | | `-' | | `-. | | / __ \ (_)
| | | __ | (_)\/ | (_) | | .-. | | .-' | | \ |__| ) (
| | | | |)| | \ / | | | | | |)| | `--. | |) \ | |
`-' |_| (_) | |\/| | `-' /( (_)/( __.' |((_)-' /(_|
'-' '-' (__) (__) (_) (__)

Link to comment
Share on other sites

do not know if is to be considered a bug or what, but bothdhose way fails if duplicate values are present in an array (because it says only in array1 while it's in both. for example double the number 10 in first array)

 

image.jpeg.9f1a974c98e9f77d824b358729b089b0.jpeg Chimp

small minds discuss people average minds discuss events great minds discuss ideas.... and use AutoIt....

Link to comment
Share on other sites

Here's one way I'd do it. I'm sure the comparisons could be done better, and getting rid of _ArraySearch would probably help too.

I used _ArrayShuffle so that I could make sure it would find the proper duplicates/unique items no matter what order they were in the arrays.

#include <Array.au3>
Global $Compare1[10] = [1, 3, 5, 6, 7, 8, 9, 10, 11, 12]
_ArrayShuffle($Compare1)

Global $Compare2[10] = [1, 2, 3, 4, 5, 6, 8, 10, 12, 13]
_ArrayShuffle($Compare2)


Global $whatsLeftOfCompare1[UBound($Compare1)]

Global $whatsLeftOfCompare2[UBound($Compare2)]

Global $whatsInBoth[100]
Global $K = 0, $L = 0
For $I = 0 To UBound($Compare1) - 1
    _ArraySearch($Compare2, $Compare1[$I])
    If Not @error Then
        $whatsInBoth[$K] = $Compare1[$I]
        $K += 1
    Else
        $whatsLeftOfCompare1[$L] = $Compare1[$I]
        $whatsLeftOfCompare2[$L] = $Compare2[$I]
        $L += 1
    EndIf
Next
$L = 0
For $I = 0 To UBound($Compare2) - 1
    _ArraySearch($Compare1, $Compare2[$I])
    If @error Then
        $whatsLeftOfCompare2[$L] = $Compare2[$I]
        $L += 1
    EndIf
Next
ReDim $whatsInBoth[$K]
ReDim $whatsLeftOfCompare1[$L]
ReDim $whatsLeftOfCompare2[$L]
_ArrayDisplay($whatsInBoth, "$whatsInBoth")
_ArrayDisplay($whatsLeftOfCompare1, "$whatsLeftOfCompare1")
_ArrayDisplay($whatsLeftOfCompare2, "$whatsLeftOfCompare2")

If I posted any code, assume that code was written using the latest release version unless stated otherwise. Also, if it doesn't work on XP I can't help with that because I don't have access to XP, and I'm not going to.
Give a programmer the correct code and he can do his work for a day. Teach a programmer to debug and he can do his work for a lifetime - by Chirag Gude
How to ask questions the smart way!

I hereby grant any person the right to use any code I post, that I am the original author of, on the autoitscript.com forums, unless I've specifically stated otherwise in the code or the thread post. If you do use my code all I ask, as a courtesy, is to make note of where you got it from.

Back up and restore Windows user files _Array.au3 - Modified array functions that include support for 2D arrays.  -  ColorChooser - An add-on for SciTE that pops up a color dialog so you can select and paste a color code into a script.  -  Customizable Splashscreen GUI w/Progress Bar - Create a custom "splash screen" GUI with a progress bar and custom label.  -  _FileGetProperty - Retrieve the properties of a file  -  SciTE Toolbar - A toolbar demo for use with the SciTE editor  -  GUIRegisterMsg demo - Demo script to show how to use the Windows messages to interact with controls and your GUI.  -   Latin Square password generator

Link to comment
Share on other sites

nah no bug, there are many cases where that will have to be modified it was just a crude example, a couple i have found are:

1) if there is dupes in the same array, or the potential, you get Chimps result, I would run arrayunique on them first if feasible.

       

2) if there are a different number of items in the arrays then one of the loops will blow up, as i am using the ubound of the target

      2a)  If there are dupes in the same array, and you perform the delete right after you find them (in the same fashion as the other arraysearch-->arraydelete, rather than using arrayunique), thus redimming and creating arrays of two different sizes, same explosion.

Edited by boththose

,-. .--. ________ .-. .-. ,---. ,-. .-. .-. .-.
|(| / /\ \ |\ /| |__ __||| | | || .-' | |/ / \ \_/ )/
(_) / /__\ \ |(\ / | )| | | `-' | | `-. | | / __ \ (_)
| | | __ | (_)\/ | (_) | | .-. | | .-' | | \ |__| ) (
| | | | |)| | \ / | | | | | |)| | `--. | |) \ | |
`-' |_| (_) | |\/| | `-' /( (_)/( __.' |((_)-' /(_|
'-' '-' (__) (__) (_) (__)

Link to comment
Share on other sites

It seems that there are no issues using Scripting.Dictionary

#include <Array.au3>

Local $a[11] = [1, 1, 3, 5, 6, 7, 8, 9, 10, 11, 12]
Local $b[12] = [1, 2, 2, 3, 4, 5, 6, 8, 10, 12, 13, 14]

Local $sda = ObjCreate("Scripting.Dictionary")
Local $sdb = ObjCreate("Scripting.Dictionary")
Local $sdc = ObjCreate("Scripting.Dictionary")

For $i In $a
    $sda.Item($i) 
Next
For $i In $b
    $sdb.Item($i)
Next

For $i In $a
    If $sdb.Exists($i) Then $sdc.Item($i)
Next
$asd3 = $sdc.Keys() 

For $i In $asd3
    If $sda.Exists($i) Then $sda.Remove($i)
    If $sdb.Exists($i) Then $sdb.Remove($i)
Next
$asd1 = $sda.Keys()
$asd2 = $sdb.Keys()

_ArrayDisplay($asd1, "$asd1")
_ArrayDisplay($asd2, "$asd2")
_ArrayDisplay($asd3, "$asd3")
Link to comment
Share on other sites

That is beautiful, "advantages of scripting.dictionary over array functions" totally needs its own thread.

,-. .--. ________ .-. .-. ,---. ,-. .-. .-. .-.
|(| / /\ \ |\ /| |__ __||| | | || .-' | |/ / \ \_/ )/
(_) / /__\ \ |(\ / | )| | | `-' | | `-. | | / __ \ (_)
| | | __ | (_)\/ | (_) | | .-. | | .-' | | \ |__| ) (
| | | | |)| | \ / | | | | | |)| | `--. | |) \ | |
`-' |_| (_) | |\/| | `-' /( (_)/( __.' |((_)-' /(_|
'-' '-' (__) (__) (_) (__)

Link to comment
Share on other sites

 

It seems that there are no issues using Scripting.Dictionary

 

In this case it works out as the scripting dictionary overwrites the duplicate key...

#include <Array.au3>

Local $a[11] = [1, 1, 3, 5, 6, 7, 8, 9, 10, 11, 12]
Local $b[12] = [1, 2, 2, 3, 4, 5, 6, 8, 10, 12, 13, 14]

Local $sda = ObjCreate("Scripting.Dictionary")
Local $sdb = ObjCreate("Scripting.Dictionary")
Local $sdc = ObjCreate("Scripting.Dictionary")

For $i In $a
    $sda.Item($i)
Next
For $i In $b
    $sdb.Item($i)
Next

; --------------------------------------
$aKeys = $sdb.Keys()
For $i = 0 To ubound($aKeys) -1
  ConsoleWrite($aKeys[$i] & @CRLF)
Next
;---------------------------------------

For $i In $a
    If $sdb.Exists($i) Then $sdc.Item($i)
Next
$asd3 = $sdc.Keys()

For $i In $asd3
    If $sda.Exists($i) Then $sda.Remove($i)
    If $sdb.Exists($i) Then $sdb.Remove($i)
Next
$asd1 = $sda.Keys()
$asd2 = $sdb.Keys()

_ArrayDisplay($asd1, "$asd1")
_ArrayDisplay($asd2, "$asd2")
_ArrayDisplay($asd3, "$asd3")

@boththose - I agree, for me personally anyway, when I stopped using VBS I also stopped using the scripting dictionary.  As mikell demonstated it may be time to start looking at it as another alternative.

kylomas

Edited by kylomas

Forum Rules         Procedure for posting code

"I like pigs.  Dogs look up to us.  Cats look down on us.  Pigs treat us as equals."

- Sir Winston Churchill

Link to comment
Share on other sites

no claim of improvement, just another one
this returns results in a 2D array
col1 contains values contained only in first array, col2 those contained only in the second one, and col3 in both

#include <Array.au3>
Local $a[11] = [1, 1, 3, 5, 6, 7, 8, 9, 10, 11, 12]
Local $b[12] = [1, 2, 2, 3, 4, 5, 6, 8, 10, 12, 13, 14]

_ArrayDisplay(_Separate($a, $b))

Func _Separate(ByRef $in0, ByRef $in1)
    $in0 = _ArrayUnique($in0, 0, Default, Default, 0)
    $in1 = _ArrayUnique($in1, 0, Default, Default, 0)
    Local $z[2] = [UBound($in0), UBound($in1)], $low = 1 * ($z[0] > $z[1]), $aTemp[$z[Not $low]][3], $aOut = $aTemp, $aNdx[3]
    For $i = 0 To $z[Not $low] - 1
        If $i < $z[0] Then $aTemp[$i][0] = $in0[$i]
        If $i < $z[1] Then $aTemp[$i][1] = $in1[$i]
    Next
    For $i = 0 To $z[$low] - 1
        $x = _ArrayFindAll($aTemp, $aTemp[$i][$low], 0, 0, 1, 0, Not $low)
        If Not @error Then ; both
            For $j = 0 To UBound($x) - 1
                $aTemp[$x[$j]][2] = 1
            Next
            $aOut[$aNdx[2]][2] = $aTemp[$i][$low]
            $aNdx[2] += 1
        Else ; only in $low
            $aOut[$aNdx[$low]][$low] = $aTemp[$i][$low]
            $aNdx[$low] += 1
        EndIf
    Next
    For $i = 0 To $z[Not $low] - 1
        If $aTemp[$i][2] <> 1 Then
            $aOut[$aNdx[Not $low]][Not $low] = $aTemp[$i][Not $low]
            $aNdx[Not $low] += 1
        EndIf
    Next
    ReDim $aOut[_ArrayMax($aNdx)][3]
    Return $aOut
EndFunc   ;==>_Separate
Edited by Chimp

 

image.jpeg.9f1a974c98e9f77d824b358729b089b0.jpeg Chimp

small minds discuss people average minds discuss events great minds discuss ideas.... and use AutoIt....

Link to comment
Share on other sites

  • 3 years later...

*

Edited by iamtheky

,-. .--. ________ .-. .-. ,---. ,-. .-. .-. .-.
|(| / /\ \ |\ /| |__ __||| | | || .-' | |/ / \ \_/ )/
(_) / /__\ \ |(\ / | )| | | `-' | | `-. | | / __ \ (_)
| | | __ | (_)\/ | (_) | | .-. | | .-' | | \ |__| ) (
| | | | |)| | \ / | | | | | |)| | `--. | |) \ | |
`-' |_| (_) | |\/| | `-' /( (_)/( __.' |((_)-' /(_|
'-' '-' (__) (__) (_) (__)

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...