MyEarth Posted February 5, 2016 Share Posted February 5, 2016 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 Link to comment Share on other sites More sharing options...
JohnOne Posted February 5, 2016 Share Posted February 5, 2016 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. AutoIt Absolute Beginners Require a serial Pause Script Video Tutorials by Morthawt ipify Monkey's are, like, natures humans. Link to comment Share on other sites More sharing options...
MyEarth Posted February 5, 2016 Author Share Posted February 5, 2016 (edited) 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 February 5, 2016 by MyEarth Link to comment Share on other sites More sharing options...
JohnOne Posted February 5, 2016 Share Posted February 5, 2016 Can you be bothered to type some code to create these two example arrays? AutoIt Absolute Beginners Require a serial Pause Script Video Tutorials by Morthawt ipify Monkey's are, like, natures humans. Link to comment Share on other sites More sharing options...
AutoBert Posted February 5, 2016 Share Posted February 5, 2016 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. Link to comment Share on other sites More sharing options...
kylomas Posted February 5, 2016 Share Posted February 5, 2016 (edited) 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 February 5, 2016 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 comment Share on other sites More sharing options...
MyEarth Posted February 6, 2016 Author Share Posted February 6, 2016 (edited) 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 February 6, 2016 by MyEarth Link to comment Share on other sites More sharing options...
mikell Posted February 6, 2016 Share Posted February 6, 2016 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 comment Share on other sites More sharing options...
MyEarth Posted February 6, 2016 Author Share Posted February 6, 2016 Cool, thanks. Just a question, your code with COM don't require any error checking except for see if the variable is an array? Link to comment Share on other sites More sharing options...
Malkey Posted February 6, 2016 Share Posted February 6, 2016 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. expandcollapse popup#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 comment Share on other sites More sharing options...
JohnOne Posted February 7, 2016 Share Posted February 7, 2016 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 comment Share on other sites More sharing options...
mikell Posted February 7, 2016 Share Posted February 7, 2016 Maybe because $a and $b are not strings ? == : Tests if two strings are equal Link to comment Share on other sites More sharing options...
JohnOne Posted February 7, 2016 Share Posted February 7, 2016 (edited) Could be a small part of the answer, but not the whole of it. ConsoleWriteLine((1 == 2)) Edited February 7, 2016 by JohnOne AutoIt Absolute Beginners Require a serial Pause Script Video Tutorials by Morthawt ipify Monkey's are, like, natures humans. Link to comment Share on other sites More sharing options...
mikell Posted February 7, 2016 Share Posted February 7, 2016 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)) Link to comment Share on other sites More sharing options...
JohnOne Posted February 7, 2016 Share Posted February 7, 2016 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. AutoIt Absolute Beginners Require a serial Pause Script Video Tutorials by Morthawt ipify Monkey's are, like, natures humans. Link to comment Share on other sites More sharing options...
mikell Posted February 7, 2016 Share Posted February 7, 2016 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 "=" Link to comment Share on other sites More sharing options...
qwert Posted February 7, 2017 Share Posted February 7, 2017 @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? Link to comment Share on other sites More sharing options...
mikell Posted February 7, 2017 Share Posted February 7, 2017 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", "") Link to comment Share on other sites More sharing options...
qwert Posted February 7, 2017 Share Posted February 7, 2017 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 comment Share on other sites More sharing options...
mikell Posted February 7, 2017 Share Posted February 7, 2017 (edited) 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 February 8, 2017 by mikell Subz 1 Link to comment Share on other sites More sharing options...
Recommended Posts
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 accountSign in
Already have an account? Sign in here.
Sign In Now