txn Posted November 5, 2013 Posted November 5, 2013 (edited) Let's say you've got a 2D array like this: Local $avArray[5][3] = [ _ ["link1", "title1", "text0"], _ ["link2", "title2", "text0"], _ ["link3", "title3", "text0"], _ ["link4", "title3", "text1"], _ ["link5", "title2", "text1"]] And you want to find the index number of the array containing "title3" and "text0". You would write something like this: For $i = 0 To UBound($avArray) - 1 $match = $avArray[$i] If StringInStr($match[1], "title3") And StringInStr($match[2], "text0") Then Return $match[0] EndIf Next Right? Now let's say that, if in $avArray there's no "text0" string, you would settle for matching only "title3". How would you do that? Do you go through $avArray again with another For/Next loop? And if you would settle also for another option (say "title2") so that just putting an Else inside the first loop wouldn't do the trick? Thanks. Edited November 5, 2013 by txn
Moderators Melba23 Posted November 5, 2013 Moderators Posted November 5, 2013 txn,This seems to work for me: expandcollapse popup#include <Constants.au3> Local $avArray[5][3] = [ _ ["link1", "title1", "text0"], _ ["link2", "title2", "text0"], _ ["link3", "title3", "text0"], _ ["link4", "title3", "text1"], _ ["link5", "title2", "text1"]] $sMatch = _Search($avArray, "title3", "text0", "??", "title2") MsgBox($MB_SYSTEMMODAL, "Found", $sMatch) ; Mode: "?." = match title only; ".?" = match text only; "??" = match both Func _Search($aArray, $sTitle, $sText, $sMode, $sAlt_Title = "", $sAlt_Text = "") Local $fFound_Title, $fFound_Text, $fFound_Alt_Title, $fFound_Alt_Text For $i = 0 To UBound($aArray) - 1 ; Clear all flags $fFound_Title = False $fFound_Text = False $fFound_Alt_Title = False $fFound_Alt_Text = False ; Look for titles If StringInStr($aArray[$i][1], $sTitle) Then $fFound_Title = True If $sAlt_Title Then If StringInStr($aArray[$i][1], $sAlt_Title) Then $fFound_Alt_Title = True EndIf ; Look for texts If StringInStr($aArray[$i][2], $sText) Then $fFound_Text = True If $sAlt_Text Then If StringInStr($aArray[$i][2], $sAlt_Text) Then $fFound_Alt_Text = True EndIf MsgBox($MB_SYSTEMMODAL, "Element: " & $i, $fFound_Title & @CRLF & $fFound_Text & @CRLF & $fFound_Alt_Title & @CRLF & $fFound_Alt_Text) ; Now check mode to see if we have a match Switch $sMode Case "?." ; Only looking for title If $fFound_Title Then Return $aArray[$i][0] ElseIf $sAlt_Title Then If $fFound_Alt_Title Then Return $aArray[$i][0] EndIf EndIf Case ".?" ; Only looking for text If $fFound_Text Then Return $aArray[$i][0] ElseIf $sAlt_Text Then If $fFound_Alt_Text Then Return $aArray[$i][0] EndIf EndIf Case "??" ; Looking for both If $fFound_Title And $fFound_Text Then Return $aArray[$i][0] Else ; Accept an alt title? If $sAlt_Title Then If $fFound_Alt_Title And $fFound_Text Then Return $aArray[$i][0] EndIf EndIf ; Accept an alt text? If $sAlt_Text Then If $fFound_Title And $fFound_Alt_Text Then Return $aArray[$i][0] EndIf EndIf ; Accept both alts? If $sAlt_Title And $sAlt_Text Then If $fFound_Alt_Title And $fFound_Alt_Text Then Return $aArray[$i][0] EndIf EndIf EndIf EndSwitch Next EndFuncI hope the parameters and logic flow are understandable, but please ask if not. M23 Any of my own code posted anywhere on the forum is available for use by others without any restriction of any kind Open spoiler to see my UDFs: Spoiler ArrayMultiColSort ---- Sort arrays on multiple columnsChooseFileFolder ---- Single and multiple selections from specified path treeview listingDate_Time_Convert -- Easily convert date/time formats, including the language usedExtMsgBox --------- A highly customisable replacement for MsgBoxGUIExtender -------- Extend and retract multiple sections within a GUIGUIFrame ---------- Subdivide GUIs into many adjustable framesGUIListViewEx ------- Insert, delete, move, drag, sort, edit and colour ListView itemsGUITreeViewEx ------ Check/clear parent and child checkboxes in a TreeViewMarquee ----------- Scrolling tickertape GUIsNoFocusLines ------- Remove the dotted focus lines from buttons, sliders, radios and checkboxesNotify ------------- Small notifications on the edge of the displayScrollbars ----------Automatically sized scrollbars with a single commandStringSize ---------- Automatically size controls to fit textToast -------------- Small GUIs which pop out of the notification area
txn Posted November 6, 2013 Author Posted November 6, 2013 (edited) Thanks for your reply Melba23. Actually I figured out I'm not dealing with a 2d array but rather with an array of arrays (returned by StringRegExp with flag 4). Does it make difference? As for your code, the parameters and logic flow are absolutely understandable, and your solution is certainly more elegant and portable than going like: For $i = 0 To UBound($avArray) - 1 $match = $avArray[$i] If StringInStr($match[1], "title3") And StringInStr($match[2], "text0") Then Return $match[0] EndIf Next For $i = 0 To UBound($avArray) - 1 $match = $avArray[$i] If StringInStr($match[1], "title3") Then Return $match[0] EndIf Next For $i = 0 To UBound($avArray) - 1 $match = $avArray[$i] If StringInStr($match[1], "title2") Then Return $match[0] EndIf Next But I see there's a lot of nested statements in your code. Is it preferable than looping through the array over and over? Edit: so my nested arrays should actually be declared like below. Sorry for misleading you, I thought that 2d arrays and nested arrays were the same thing (and to be honest I still don't really get the difference ) Global $one[3] = ["link1", "title1", "text0"] Global $two[3] = ["link2", "title2", "text0"] Global $three[3] = ["link3", "title4", "text0"] Global $four[3] = ["link4", "title4", "text1"] Global $five[3] = ["link5", "title6", "text1"] Global $avArray[5] = [$one, $two, $three, $four, $five] Edited November 6, 2013 by txn
kylomas Posted November 6, 2013 Posted November 6, 2013 (edited) txn, There is a tutorial on arrays here. Briefly, you can visualize 1D arrays as a list and 2D arrays as a spreadsheet. In your example you have a 1D array where each element (row) is an array. This is distinctly different from a 2D array and rarely used (some of the heavy hitters may disagree). Maybe the following example will help... expandcollapse popup; $avArray is a 1D array where each cell points to a 1D array. ; This is completely different from a 2D array both in concept and use. Global $one[3] = ["link1", "title1", "text0"] Global $two[3] = ["link2", "title2", "text0"] Global $three[3] = ["link3", "title4", "text0"] Global $four[3] = ["link4", "title4", "text1"] Global $five[3] = ["link5", "title6", "text1"] Global $avArray1[5] = [$one, $two, $three, $four, $five] ; The above could be expressed as a 2D array as follows: Global $avArray2[5][3] = [ _ ["link1", "title1", "text0"], _ ["link2", "title2", "text0"], _ ["link3", "title4", "text0"], _ ["link4", "title4", "text1"], _ ["link5", "title6", "text1"] _ ] ; Each "row" of $avArray1 can be accessed as follows. Each element needs to be copied to an interim array ; (there may some other way to do this that I am not aware of) ConsoleWrite(@lf & '!Printing $avArray1[$one]' & @LF) local $aTmp = $avArray1[$one] for $1 = 0 to ubound($aTmp) - 1 ConsoleWrite($aTmp[$1] & @LF) Next ; The above would need to be repeated for each "row" of $avArray1 whereas a 2D array is much easier to access: ConsoleWrite(@lf & '!Printing $avArray2' & @LF) for $1 = 0 to ubound($avArray2) - 1 for $2 = 0 to ubound($avArray2,2) - 1 ; note the use of the dimension indicator ConsoleWrite($avArray2[$1][$2] & ' ') Next ConsoleWrite(@LF) Next ConsoleWrite(@LF) kylomas edit: But I see there's a lot of nested statements in your code. Is it preferable than looping through the array over and over? In the _Search function the top for..next loop is used to iterate through the array testing for equality and setting switches. The case statement (switch...endswitch) is then used to decide what to return to the caller. That way the array is only pased once. Edited November 6, 2013 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
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