# 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

##### Share on other sites

If time is money, you should give as much information as possible in your first post, not least some example arrays and a criteria as to what you deem to be difference.

Monkey's are, like, natures humans.

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

##### Share on other sites

Can you be bothered to type some code to create these two example arrays?

Monkey's are, like, natures humans.

##### Share on other sites

What have you tried already: script? Because you are not in restaurant where you can order what you want. Make a example which fills the arrays whith test elements, and then i or somebody else try to find the fastest solution.

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

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

##### 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")```

##### Share on other sites

Cool, thanks. Just a question, your code with COM don't require any error checking except for see if the variable is an array?

##### 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(_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```

##### 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```

Monkey's are, like, natures humans.

##### Share on other sites

Maybe because \$a and \$b are not strings ?

 == : Tests if two strings are equal

##### Share on other sites

Could be a small part of the answer, but not the whole of it.

`ConsoleWriteLine((1 == 2))`

Edited by JohnOne

Monkey's are, like, natures humans.

##### Share on other sites

Sorry, it was a small part of the answer indeed

== : Tests if two strings are equal. Case sensitive. The left and right values are converted to strings if they are not strings already.

```local \$a = [1,1,1,4,5,6,7,8,9,0,'C']
Msgbox(0,"", String(\$a))

local \$b = 2
Msgbox(0,"", String(\$b))```

##### Share on other sites

See, if you just have

`ConsoleWriteLine((\$a = \$b))`

It will evaluate to false, so for reference, I'd like to know what actual comparison occurs with operands of array.

Monkey's are, like, natures humans.

##### Share on other sites

I understand
I just had a look into the wiki here , but the sample code brings no clarification because it uses the operator "==" (which obviously can't work) and not "="

##### Share on other sites

@Malkey: I was using _ArrayDiff with arrays of directories that have "\" as the last character of each element ... and the Diff operation lets them through.

Any suggestion of how to make it work with \'s?

##### Share on other sites
3 hours ago, qwert said:

Any suggestion of how to make it work with \'s?

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

or...

apply the change below to Malkey's _ArrayDiff

`\$sArrayToString = StringRegExpReplace(\$sArrayToString, "(?m)^\Q" & \$array1[\$i] & "\E\R", "")`

##### Share on other sites
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"]

##### 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
• 1

## Create an account

Register a new account

×

• Wiki

• Back

• Git