NDog Posted October 25, 2012 Share Posted October 25, 2012 (edited) I need help with comparing arrays. It is a two part question. QUESTION 1 $array1 contains unique values, (eg same value cannot repeat twice). $array1 does not change $array2 contains only values from $array1, but these can be repeated. $array2 grows larger. example ($array2 does not contain all the elements of $array1 yet, continue) $array1 = {1,2,3,4,A,B,C,D} $array2 = {A,B,3,4,A,A} What I want to happen is as soon as all the values in $array2 match $array1, then I want it to perform a function example ($array2 contains all the elements of $array1. do something) $array1 = {1,2,3,4,A,B,C,D} $array2 = {A,B,3,4,A,A,1,1,2,C,D} QUESTION 2 I am looping through $array1 and adding elements from $array1 to $array2. How can I ensure that if an element from $array1 has already been assigned to $array2, not to add it to $array2 again example $array1 = {1,2,3,4,A,B,C,D} $array2 = {2,A,B} If while looping through $array1 if it matches "2" or "A" or "B" (from $array2), then don't add to the $array2 and continue to loop though till it gets a match eg "1" and add this to $array2 (and then perform a function related to "1"). I hope this makes sense. Edited October 28, 2012 by NDog Link to comment Share on other sites More sharing options...
UEZ Posted October 25, 2012 Share Posted October 25, 2012 Make array 2 unique and compare both arrays. If you wish you can sort both arrays to speed up array compare. Br, UEZ Please don't send me any personal message and ask for support! I will not reply! Selection of finest graphical examples at Codepen.io The own fart smells best! ✌Her 'sikim hıyar' diyene bir avuç tuz alıp koşma!¯\_(ツ)_/¯ ٩(●̮̮̃•̃)۶ ٩(-̮̮̃-̃)۶ૐ Link to comment Share on other sites More sharing options...
Robjong Posted October 25, 2012 Share Posted October 25, 2012 (edited) Hi, here is one way how you could do it... - Make the second array unique. _ArrayUnique - Check if the arrays are the same size, if they are not they can not be equal and we stop here. UBound - Sort second array. _ArraySort - Loop through the arrays and compare values. For...To...Next Edit: changed "both arrays" to "second array" as the first array does not change. Edited October 25, 2012 by Robjong Link to comment Share on other sites More sharing options...
NDog Posted October 25, 2012 Author Share Posted October 25, 2012 (edited) Here are some real values, where $users would be $array1 and $doneusers would be $array2, I haven't managed to find the solution yet but will experiment with _arrayunique #Include <Array.au3> Local $users[3][4] $users[0][0]="bob" $users[1][0]="mary" $users[2][0]="janet" $users[0][1]="bob is your uncle" $users[1][1]="mary is your mother" $users[2][1]="janet is friend" $users[0][2]="fish" $users[1][2]="meat" $users[2][2]="chicken" $users[0][3]="arizona" $users[1][3]="kentucky" $users[2][3]="kentucky" Local $doneusers[5] = ["bob", "mary", "bob", "mary", "mary"] _ArrayDisplay($users,"$users") _ArrayDisplay($doneusers,"$doneusers") Edited October 25, 2012 by NDog Link to comment Share on other sites More sharing options...
incepator Posted October 25, 2012 Share Posted October 25, 2012 #include <Array.au3> _ArrayUnique function.... _ArrayUnique($aArray [, $iDimension = 1 [, $iBase = 0 [, $iCase = 0 [, $vDelim = "|"]]]]) Autoit Help File... Link to comment Share on other sites More sharing options...
NDog Posted October 25, 2012 Author Share Posted October 25, 2012 (edited) I have got the _ArrayUnique part working . I am just working on the last part- Loop through the arrays and compare values.For...To...NextJust trying to figure what exactly I need to compare in order not to redo an already used value, this is related to question 2For example; determine if user has already been processed For $i = 0 To UBound($users,1) - 1 For $j = 1 To $doneusers[0] ; contains the amount of records ConsoleWrite("$users " & $i & ": " &$users[$i][$uname]&@CRLF) ConsoleWrite("$doneusers " & $j & ": " &$doneusers[$j]&@CRLF) Next NextWhat am I supposed to use to compare if a user has not already been processed? This is because I will run this loop from the beginning everytime, so I am confused.I am really close, thanks for your advice so far Edited October 25, 2012 by NDog Link to comment Share on other sites More sharing options...
UEZ Posted October 25, 2012 Share Posted October 25, 2012 (edited) Try this: #include <Array.au3> #region question 1 Global $array1[8] = [1,2,3,4,"A","B","C","D"] Global $array2[11] = ["A","B",3,4,"A","A",1,1,2,"C","D"] $array2_unique = _ArrayUnique($array2) _ArraySort($array2_unique, 0, 1) $string1 = _ArrayToString($array1) $string2 = _ArrayToString($array2_unique, "|", 1) If $string1 = $string2 Then MsgBox(0, "Equal", "Action") Else MsgBox(0, "Not Equal", "No Go!") EndIf #endregion #region question2 Global $array1[8] = [1,2,3,4,"A","B","C","D"] Global $array2[3] = [2,"A","B"] _ArrayConcatenate($array2, $array1) $array2 = _ArrayUnique($array2) _ArraySort($array2, 0, 1) _ArrayDelete($array2, 0) _ArrayDisplay($array2) #endregion Br, UEZ Edited October 25, 2012 by UEZ Please don't send me any personal message and ask for support! I will not reply! Selection of finest graphical examples at Codepen.io The own fart smells best! ✌Her 'sikim hıyar' diyene bir avuç tuz alıp koşma!¯\_(ツ)_/¯ ٩(●̮̮̃•̃)۶ ٩(-̮̮̃-̃)۶ૐ Link to comment Share on other sites More sharing options...
Robjong Posted October 25, 2012 Share Posted October 25, 2012 Here is an example of what I had in mind... expandcollapse popup#include <Array.au3> Local $sSomeValueToAdd = "janet" ; some new value to add Local $doneusers[5] = ["bob", "mary", "bob", "mary", "mary"] Local $users[3][4] $users[0][0] = "bob" $users[1][0] = "mary" $users[2][0] = "janet" $users[0][1] = "bob is your uncle" $users[1][1] = "mary is your mother" $users[2][1] = "janet is friend" $users[0][2] = "fish" $users[1][2] = "meat" $users[2][2] = "chicken" $users[0][3] = "arizona" $users[1][3] = "kentucky" $users[2][3] = "kentucky" ; array1, this only has to be done once, as long as the $users array does not change Local $array1 = _ArrayUnique($users, 1) ; 2D so we specify the dimension we need _ArraySort($array1, 0, 1) ; sort array, start at 1 as 0 holds the total ; do this whenever $doneusers has changed, to make comparing easier Local $array2 = _ArrayUnique($doneusers) _ArraySort($array2, 0, 1) ; sort array, start at 1 as 0 holds the total ; view the arrays ;~ _ArrayDisplay($array1,"$array1") ;~ _ArrayDisplay($array2,"$array2") #region - Check if the arrays are equal Local $fEqual = False If $array1[0] == $array2[0] Then ; arrays are of equal size, check if all values from array1 are present in array2 $fEqual = True For $i = 1 To $array1[0] Step 1 If $array1[$i] <> $array2[$i] Then ; compare elements $fEqual = False ExitLoop EndIf Next EndIf If $fEqual Then ; the arrays are the same, do you need to do something with this information? ConsoleWrite("-> ARRAYS ARE EQUAL" & @LF) ; ... Else ConsoleWrite("-> ARRAYS ARE NOT EQUAL" & @LF) ; ... EndIf #endregion - Check if the arrays are equal #region - Check if some value already exists in the array $sSomeValueToAdd = StringLower($sSomeValueToAdd) ; case insensetive compare so make the string lower case Local $fExists = False For $i = 1 To $array2[0] Step 1 If StringLower($array2[$i]) == $sSomeValueToAdd Then ; compare value and element $fExists = True ; the values already exists ExitLoop EndIf Next If $fExists Then ; the value is not present in the array, do you need to do something with this information? ConsoleWrite("-> VALUE """ & $sSomeValueToAdd & """ IS ALREADY PRESENT ARRAY2" & @LF) ; ... Else ConsoleWrite("-> VALUE """ & $sSomeValueToAdd & """ IS NOT PRESENT ARRAY2" & @LF) _ArrayAdd($doneusers, $sSomeValueToAdd) ; add the value to the array ($doneusers = $array2) ; ... EndIf ; view the array $doneusers ;~ $doneusers = _ArrayUnique($doneusers) ; is needed now but should not be if you do it right?! _ArrayDisplay($doneusers, "$doneusers") #endregion - Check if some value already exists in the array Link to comment Share on other sites More sharing options...
NDog Posted October 28, 2012 Author Share Posted October 28, 2012 (edited) Thanks UEZ and Robjong for your suggestions.I wasn't able to figure out how to use region 2 in UEZ example in a usable way, eg in a loop, but the region 1 makes sense and I am using it.As for question 2 it is not answered.I have two arrays$users, contains all users, eg bob, janet, mary, helen, grant$doneusers, contains users that have been done, bob, grantHow can I make a loop that scans through $users and finds matches that have do not exist in $doneusers, and then do something, afterwards adding themselves to $doneusers, and then repeating the process until all the $users end up in $doneusers, and then doing something else?This is the best I can do, but I am stuckexpandcollapse popup#include <Array.au3> Global $users[5] = ["bob", "janet", "mary", "helen", "grant"] Global $doneusers[2] = ["bob", "grant"] ;~ _ArrayDisplay($users, "$users") ;~ _ArrayDisplay($doneusers, "$doneusers") SetupNextLogin() Func SetupNextLogin() ; don't process already processed users ; $fExists 0 = not initialised ; $fExists 1 = no match found ; $fExists 2 = match was found Local $fExists = 0 For $i = 0 To UBound($users,1) - 1 For $j = 0 To UBound($doneusers,1) - 1 ConsoleWrite("$users " & $i & ": " &$users[$i]&@CRLF) ConsoleWrite("$doneusers " & $j & ": " &$doneusers[$j]&@CRLF) ConsoleWrite("====="&@CRLF) If $users[$i] <> $doneusers[$j] Then $fExists = 1 EndIf If $users[$i] = $doneusers[$j] Then $fExists = 2 EndIf Next Next Select Case $fExists = 0 ConsoleWrite("~~~0 - Loop user~~~ "&@CRLF) Case $fExists = 1 ConsoleWrite("~~~1 - Loop user~~~ "&@CRLF) Case $fExists = 2 ConsoleWrite("~~~2 - Loop user~~~ "&@CRLF) EndSelect EndFunc ;~ _ArrayDisplay($users, "$users") ;~ _ArrayDisplay($doneusers, "$doneusers") Edited October 28, 2012 by NDog Link to comment Share on other sites More sharing options...
Spiff59 Posted October 28, 2012 Share Posted October 28, 2012 Use a flag that you clear before the inner loop, set inside the inner loop, and test after the inner loop. Global $users[5] = ["bob", "janet", "mary", "helen", "grant"] Global $doneusers[2] = ["bob", "grant"] Global $found ; determine if user has already been processed For $i = 0 To UBound($users,1) - 1 $found = 0 For $j = 0 To UBound($doneusers,1) - 1 If $doneusers[$j] = $users[$i] Then $found = 1 ExitLoop EndIf Next If $found = 1 Then MsgBox(0,"",$users[$i] & " found") Else MsgBox(0,"",$users[$i] & " not found") EndIf Next Link to comment Share on other sites More sharing options...
NDog Posted October 28, 2012 Author Share Posted October 28, 2012 (edited) Thanks for your input Spiff59 but I am not trying to determine if a user is found or not. I am trying to determine if the user is only not found and then add another $user to $doneusers (eg add mary to $doneusers). Leave the loop entirely, do A. If all is equal then do B. The reason for this is because the script actually exits once it cant find a user (does A) and saves its variables to a text file. The next time the script is run it gets the variables from the text file and repeats the process until it does B. I hope this makes sense. Eg expandcollapse popupscript.exe - first time Global $users[5] = ["bob", "janet", "mary", "helen", "grant"] Global $doneusers[1] .. Noone has been processed, do something for bob FileWrite("doneusers.txt, "bob" & @CRLF) Exit script.exe - second time Global $users[5] = ["bob", "janet", "mary", "helen", "grant"] Global $doneusers[1] = ["bob"] .. bob has already been processed, do something for janet FileWrite("doneusers.txt, "janet" & @CRLF) Exit script.exe - third time Global $users[5] = ["bob", "janet", "mary", "helen", "grant"] Global $doneusers[2] = ["bob", "janet"] .. bob and janet have already been processed, do something for mary FileWrite("doneusers.txt, "mary" & @CRLF) Exit script.exe - fourth time Global $users[5] = ["bob", "janet", "mary", "helen", "grant"] Global $doneusers[3] = ["bob", "janet", "mary"] .. bob, janet and mary have already been processed, do something for helen FileWrite("doneusers.txt, "helen" & @CRLF) Exit script.exe - fifth time Global $users[5] = ["bob", "janet", "mary", "helen", "grant"] Global $doneusers[4] = ["bob", "janet", "mary", "helen"] .. bob, janet, mary and helen have already been processed, do something for grant FileWrite("doneusers.txt, "grant" & @CRLF) Exit script.exe - sixth time Global $users[5] = ["bob", "janet", "mary", "helen", "grant"] Global $doneusers[5] = ["bob", "janet", "mary", "helen", "grant"] .. bob, janet, mary, helen and grant have all been processed. All done! FileDelete("doneusers.txt') Exit Edited October 28, 2012 by NDog Link to comment Share on other sites More sharing options...
NDog Posted October 28, 2012 Author Share Posted October 28, 2012 I have solved this problem. It may not be as elegant as it could be. I decided to create a temporary array and populate it with all the users, then work through and blank each user from that array that had been processed. expandcollapse popup; make a temporary array for $users Dim $tmpusers[1] For $i = 0 To UBound($users,1) - 1 _ArrayAdd($tmpusers,$users[$i][$uname]) Next _ArrayDelete($tmpusers,0) ;~ _ArraySort($tmpusers) ; must do this ;~ _ArrayDisplay($tmpusers,"$tmpusers") ; delete non matching users in $tmpusers array ((not doing this as it messes with the $i loop and cant be considered reliable)) ; http://www.autoitscript.com/forum/topic/131736-ietablegetcollection-ietablewritetoarray-and-finally-arraydelete/ ;~ _ArraySort($doneusers) ; must do this ;~ _ArrayDisplay($tmpusers,"$tmpusers") ;~ _ArrayDisplay($doneusers,"$doneusers") For $i = UBound($tmpusers,1) - 1 to 0 Step - 1 ; need to work backwards as the _arraydelete function below reduces the size of the array each time it is called For $j = 0 To UBound($doneusers,1) - 1 ;~ ConsoleWrite("$tmpusers " & $i & ": " &$tmpusers[$i]&@CRLF) ;~ ConsoleWrite("$doneusers " & $j & ": " &$doneusers[$j]&@CRLF) If $tmpusers[$i] = $doneusers[$j] Then ;~ ConsoleWrite("User being deleted from $tmpusers " & $i & ": " &$tmpusers[$i]&@CRLF) ;~ _ArrayDelete($tmpusers, $i) ;~ ConsoleWrite("User was deleted from $tmpusers " & $i & ": " &$tmpusers[$i]&@CRLF) ;~ ConsoleWrite("User being blanked from $tmpusers " & $i & ": " &$tmpusers[$i]&@CRLF) $tmpusers[$i] = "" EndIf Next Next ;~ _ArrayDisplay($tmpusers,"$tmpusers") ; Debug, all values should match and these are non processed users ;~ For $i = 0 To UBound($users,1) - 1 ;~ For $j = 0 To UBound($tmpusers,1) - 1 ;~ If $users[$i][$uname] = $tmpusers[$j] Then ;~ ConsoleWrite("$users " & $i & ": " &$users[$i][$uname]&@CRLF) ;~ ConsoleWrite("$tmpusers " & $j & ": " &$tmpusers[$j]&@CRLF) ;~ EndIf ;~ Next ;~ Next ; Setup next user to be processed, set as $nextuser For $i = 0 To UBound($tmpusers,1) - 1 If $tmpusers[$i] <> "" Then ConsoleWrite("$nextuser: " &$tmpusers[$i]&@CRLF) $nextuser = $tmpusers[$i] ExitLoop EndIf Next 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