Jump to content

Difference arrays of different size


Recommended Posts

Hello, searching around has only confuse my ideas. I need to compare two 1D array, the have different size ( the first is smaller then the second ) and i need to get only the difference between the arrays. Fastest as possible, not case sensitive because they are unique value, is not very large min 200 max 700 or more but time is money so :shifty:

Link to post
Share on other sites

I can't post it, there are sensible information inside. The entry is composed by single word, without any space, can contains also numbers. I think is already sorted but i'm not sure about it. About the "difference" i mean

array1 = abc def ghi

array2 = abc cde def ghi

The result i want is "cde" because isn't present in the first array. The first array as i have said before is smaller or equal then the second one. I think is all. thanks for your help.

Edited by MyEarth
Link to post
Share on other sites

MyEarth,

Define "difference" between arrays.

kylomas

edit: For example, what is the difference between these two arrays

local $a1 = [1,1,1,4,5,6,7,8,9,0]
local $a2 = [3,4,5,6,7,8,9,0,'a','b',1,2]

 

Edited by kylomas
question

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 post
Share on other sites

Kylomas, i think the difference are 2,3,a,b so the entry missing from the first array but present in the second one. No duplicate will be present in the array so will never happen 1,1,1,1 but only 1 one, anyway i can use ArrayUnique before if i'll found some. I'll just want to know what entry from the second array are not present in the first one, the "difference" i don't know how to explain better. AutoBert a pizza for me, thanks...

EDIT: I think i have found the script i need:

 

I'll test it more.

 

Edited by MyEarth
Link to post
Share on other sites

Easier and faster  :)

#include <Array.au3>

local $a = [1,1,1,4,5,6,7,8,9,0,'C']
local $b = [3,4,5,6,7,8,9,0,'a','b','c',1,2]

Local $sdb = ObjCreate("Scripting.Dictionary")
$sdb.CompareMode = 1   ; case insensitive
For $i In $b
    $sdb.Item($i)
Next
For $i In $a
    If $sdb.Exists($i) Then $sdb.Remove($i)
Next
$asdb = $sdb.Keys()
_ArrayDisplay($asdb, "$asdb")

 

Link to post
Share on other sites

Using the same data as follows on mikell's example, post#8, I got 11 ms.
My tests took about 24 ms.

Although my examples are slower by about 13 ms, I still posted because of the possible options made available.

#include <Array.au3>

;Local $aArray1 = ["abc", "jkl", "def", "ghi"]
;Local $aArray2 = ["abc", "cde", "def", "ghi", "hij"]

;#cs
; ----- Create sample arrays ------------
Global $aArray1[500]
For $n = 0 To UBound($aArray1) - 1
    $aArray1[$n] = ($n * 2) + 1
Next
Global $aArray2[1000]
For $n = 0 To UBound($aArray2) - 1
    $aArray2[$n] = $n; Odd numbers only
Next
; -----> End of Create sample arrays ------------
;#ce

Global $iTimer = TimerInit()
ConsoleWrite("Elements in $array2 but not in $array1" & @LF)
ConsoleWrite(_ArrayDiff($aArray1, $aArray2) & @LF)
ConsoleWrite(TimerDiff($iTimer) & " ms ===========" & @LF) ; 24 ms

Global $iTimer = TimerInit()
ConsoleWrite("Elements in $array1 but not in $array2" & @LF) ; 24 ms
ConsoleWrite(_ArrayDiff($aArray1, $aArray2, 2) & @LF)
ConsoleWrite(TimerDiff($iTimer) & " ms ===========" & @LF)

Global $iTimer = TimerInit()
ConsoleWrite("Elements Not found in both arrays." & @LF)
ConsoleWrite(_ArrayDiff($aArray1, $aArray2, 3) & @LF)
ConsoleWrite(TimerDiff($iTimer) & " ms ===========" & @LF) ; 23 ms

Global $iTimer = TimerInit()
$arr = _ArrayDiff($aArray1, $aArray2, 3, 0)
_ArrayDisplay($arr, TimerDiff($iTimer) & " ms Elements Not found in both arrays.") ; 24 ms


; -------------------------------------------------
; Function:  _ArrayDiff
; Purpose:  Comparing elements in two arrays and returning the differences depending on the value of the parameter $iRet.
; Parameter:-
;           $array1 and $array2 are the arrays to be compared.
;           $iRet = 1 ; Returns elements in $array2 but not in $array1. (default)
;           $iRet = 2 ; Returns elements in $array1 but not in $array2.
;           $iRet = 3 ; Returns elements Not found in both arrays.
;           $String = 1 ; Returns elements as a string separated by @lf. (default)
;           $String = 0 ; Returns elements as an array.
; Author: Malkey
; -------------------------------------------------
Func _ArrayDiff(ByRef $array1, ByRef $array2, $iRet = 1, $String = 1)
    If (Not IsArray($array1)) Or (Not IsArray($array2)) Then Return SetError(1, 0, -1)
    Local $sArrayToString = _ArrayToString($array2, @LF) & @LF
    Local $sString2
    For $i = 0 To UBound($array1) - 1
        $sArrayToString = StringRegExpReplace($sArrayToString, "(?m)^" & $array1[$i] & "\R", "")
        If @extended = 0 Then $sString2 &= $array1[$i] & @LF ; Check items in $array1 but not in $array2
    Next
    Switch $iRet
        Case 1
            $sRet = StringStripWS($sArrayToString, 2)
        Case 2
            $sRet = StringStripWS($sString2, 2)
        Case 3
            $sRet = StringStripWS($sArrayToString & $sString2, 2)
    EndSwitch
    
    ;Return array or string
    If $String Then
        Return $sRet
    Else
        Return StringSplit($sRet, @LF, 2)
    EndIf
EndFunc   ;==>_ArrayDiff


 

Link to post
Share on other sites

I'm sure I've known the answer to this before, but I've forgotten and it is thread relevant.

Why does this expression evaluate as true?

local $a = [1,1,1,4,5,6,7,8,9,0,'C']
local $b = [3,4,5,6,7,8,9,0,'a','b','c',1,2]

ConsoleWriteLine(($a == $b))

Func ConsoleWriteLine($msg)
    ConsoleWrite($msg & @CRLF)
EndFunc

 

AutoIt Absolute Beginners    Require a serial    Pause Script    Video Tutorials by Morthawt   ipify 

Monkey's are, like, natures humans.

Link to post
Share on other sites
  • 1 year later...
Quote

Use a Scripting.Dictionary based code like mine in post#8

Actually, I tried your method, first ... and came up with a "null" array.  Since I know nothing about Objects and their use, I switched to Malkey's function.

So, thanks for the suggestion for Malkey's script.  It works.  (I'm afraid I've never gotten the hang of reading RegExp's.)

Non-the-less, would you mind showing your method using the following arrays?  I'd like to understand how to use it.  From the discussion, it seems to be faster.

Quote

Local $aArray1 = ["abc", "jkl", "def\", "ghi", "Users\"]
Local $aArray2 = ["abc", "cde", "Users\", "def\", "ghi", "hij"]

 

Link to post
Share on other sites

Something like this should work  :)

#include <Array.au3>

local $a = ["abc", "jkl", "def\", "ghi", "Users\"]
local $b = ["abc", "cde", "Users\", "def\", "ghi", "hij"] 

; create 3 empty dictionaries
Local $sda = ObjCreate("Scripting.Dictionary")
Local $sdb = ObjCreate("Scripting.Dictionary")
Local $sdc = ObjCreate("Scripting.Dictionary")
; set comparemode property
$sda.CompareMode = 1   ; case insensitive
$sdb.CompareMode = 1  
; populate 'a' and 'b' dictionaries with the content of 'a' and 'b' arrays
; the elements are added as keys
For $i In $a
    $sda.Item($i)
Next
For $i In $b
    $sdb.Item($i)
Next
; check if elements in array 'a' exist as keys in dictionary 'b'
; if not then add them to dictionary 'c'
For $i In $a
    If not $sdb.Exists($i) Then $sdc.Item($i)
Next
; check if elements in array 'b' exist as keys in dictionary 'a'
; if not then add them to dictionary 'c'
For $i In $b
    If not $sda.Exists($i) Then $sdc.Item($i)
Next
; return the array of all keys from dictionary 'c'
$asdc = $sdc.Keys()
_ArrayDisplay($asdc, "$asdc")

Edit
another example in this topic - post#10

Edited by mikell
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
  • Recently Browsing   0 members

    No registered users viewing this page.

×
×
  • Create New...