seandisanti Posted July 29, 2005 Share Posted July 29, 2005 (edited) This is a little UDF i kind of got inspiration from that 'StringInChar' topic. This one takes 2 strings, the search string and a sub string, and it returns an array, per convention element 0 of the array contains the number of elements, (or occurances)and each of the other elements contains a position... Func StringSubCount($ack, $arg);$ack and arg are source and sub string to search for $counter = 0 Dim $blah[1] for $i = 1 to StringLen($ack) if StringMid($ack,$i,StringLen($arg)) = $arg then $counter = $counter + 1 _ArrayAdd($blah,$i) $blah[0] = $counter EndIf Next Return $blah EndFunc to see this in action, i used this code while writing it to check output. #include <StringSubCount.au3> $foo = "this is a test of how well this UDF counts the number of occurances of a sub string in a given string" $bar = "this" dim $blah[StringLen($foo)] $blah = StringSubCount($foo,$bar) _ArrayDisplay($blah,"test") ***edit*** not sure if this is similar to any others already created, if it is i'm sorry, i just kind of did it then decided to post it.... i totally forgot to check if there was something similar out there... Edited July 29, 2005 by cameronsdad Link to comment Share on other sites More sharing options...
blindwig Posted July 29, 2005 Share Posted July 29, 2005 (edited) Looks good, but I continue to beg people not to use _ArrayAdd inside a loop ... And just for completeness, I'll throw in a CaseSense option. And just to be anal, I will use sensical variable names Func StringSubCount($String, $Sub, $CaseSense = 0) Local $i, $sl = StringLen($String), $ssl=StringLen($Sub), $Results[$sl+1] for $i = 1 to $sl if (Not $CaseSense And StringMid($String,$i,$ssl) = $Sub) Or ($CaseSense And StringMid($String,$i,$ssl) == $Sub) then $Results[0] += 1 $Results[$Results[0]] = $i EndIf Next ReDim $Results[$Results[0]+1] Return $Results EndFunc Edited July 29, 2005 by blindwig My UDF Threads:Pseudo-Hash: Binary Trees, Flat TablesFiles: Filter by Attribute, Tree List, Recursive Find, Recursive Folders Size, exported to XMLArrays: Nested, Pull Common Elements, Display 2dSystem: Expand Environment Strings, List Drives, List USB DrivesMisc: Multi-Layer Progress Bars, Binary FlagsStrings: Find Char(s) in String, Find String in SetOther UDF Threads I Participated:Base64 Conversions Link to comment Share on other sites More sharing options...
seandisanti Posted July 29, 2005 Author Share Posted July 29, 2005 Looks good, but I continue to beg people not to use _ArrayAdd inside a loop ...And just for completeness, I'll throw in a CaseSense option.And just to be anal, I will use sensical variable names Func StringSubCount($String, $Sub, $CaseSense = 0) Local $i, $sl = StringLen($String), $ssl=StringLen($Sub), $Results[$sl+1] for $i = 1 to $sl if (Not $CaseSense And StringMid($String,$i,$ssl) = $Sub) Or ($CaseSense And StringMid($String,$i,$ssl) == $Sub) then $Results[0] += 1 $Results[$Results[0]] = $i EndIf Next ReDim $Results[$Results[0]+1] Return $Results EndFunc<{POST_SNAPBACK}>i like the way you handled the array, and the variable name were a good touch, but case sense? are you mad?!I'm just kidding. sorry i didn't even think about case when i was making it because the things i would use it for are typically all generated in all uppercase, and i typically type in all lowercase, so i just took the easy way out... Link to comment Share on other sites More sharing options...
blindwig Posted July 29, 2005 Share Posted July 29, 2005 I'm just kidding. sorry i didn't even think about case when i was making it because the things i would use it for are typically all generated in all uppercase, and i typically type in all lowercase, so i just took the easy way out...<{POST_SNAPBACK}>Yeah, I hardly ever need case sense, but I write it in all my string functions because on the day when I do need it, I don't want to have to go back and rewrite all my functions. My UDF Threads:Pseudo-Hash: Binary Trees, Flat TablesFiles: Filter by Attribute, Tree List, Recursive Find, Recursive Folders Size, exported to XMLArrays: Nested, Pull Common Elements, Display 2dSystem: Expand Environment Strings, List Drives, List USB DrivesMisc: Multi-Layer Progress Bars, Binary FlagsStrings: Find Char(s) in String, Find String in SetOther UDF Threads I Participated:Base64 Conversions Link to comment Share on other sites More sharing options...
buzz44 Posted July 30, 2005 Share Posted July 30, 2005 Looks good, but I continue to beg people not to use _ArrayAdd inside a loop ...<{POST_SNAPBACK}> Just wondering, why don't you like using _ArrayAdd() in a loop? qq Link to comment Share on other sites More sharing options...
LxP Posted July 30, 2005 Share Posted July 30, 2005 (edited) _ArrayAdd() uses ReDim, which I imagine would internally involve creating a new array in memory that's larger, copying the values one-by-one to the new array and deleting the old array.All of this takes time and so a loop using _ArrayAdd() would most likely be considerably slower than a loop that doesn't. In most cases it would be possible to determine how many extra elements are needed and then resize the array in one go before using a For..Next loop to populate it with data. Edited July 30, 2005 by LxP Link to comment Share on other sites More sharing options...
blindwig Posted July 30, 2005 Share Posted July 30, 2005 Just wondering, why don't you like using _ArrayAdd() in a loop?<{POST_SNAPBACK}>Look at the code for _ArrayAdd() - it ReDims the array everytime you add an element. That's so slow and memory intensive - why not just make the array big enough to hold all the elements you need? Or make it too big (just in case) and then trim it when you're done?_ArrayAdd() ReDims the array by 1 element at a time. My own version (called _Array1Add() ) doubles the array each time, so it makes my loops exponentially faster than using the stock _ArrayAdd() functions. My UDF Threads:Pseudo-Hash: Binary Trees, Flat TablesFiles: Filter by Attribute, Tree List, Recursive Find, Recursive Folders Size, exported to XMLArrays: Nested, Pull Common Elements, Display 2dSystem: Expand Environment Strings, List Drives, List USB DrivesMisc: Multi-Layer Progress Bars, Binary FlagsStrings: Find Char(s) in String, Find String in SetOther UDF Threads I Participated:Base64 Conversions Link to comment Share on other sites More sharing options...
buzz44 Posted July 30, 2005 Share Posted July 30, 2005 Thanks both for clearly up. I didn't bother to look at the code for _ArrayAdd() lol. I think now I have to go back over some old scripts and fix this, where speed is a comfort for the user. qq Link to comment Share on other sites More sharing options...
erifash Posted July 30, 2005 Share Posted July 30, 2005 Hey, that's alot like my _StringFindOccurances function: Func _StringFindOccurances($sStr1, $sStr2) For $i = 1 to StringLen($sStr1) If not StringInStr($sStr1, $sStr2, 1, $i) Then ExitLoop Next Return $i - 1 EndFunc ...only better. Great job! My UDFs:_FilePrint() | _ProcessGetName() | _Degree() and _Radian()My Scripts:Drive Lock - Computer Lock Using a Flash DriveAU3Chat - Simple Multiuser TCP ChatroomStringChunk - Split a String Into Equal PartsAutoProxy - Custom Webserver Link to comment Share on other sites More sharing options...
blindwig Posted July 30, 2005 Share Posted July 30, 2005 Hey, that's alot like my _StringFindOccurances function:Func _StringFindOccurances($sStr1, $sStr2) For $i = 1 to StringLen($sStr1) If not StringInStr($sStr1, $sStr2, 1, $i) Then ExitLoop Next Return $i - 1 EndFunc...only better. Great job! <{POST_SNAPBACK}>It's a good function, I've got one something like that as well.But it looks like the OP was looking for a list of the occurances, not just the total count, which is why he's using an array. My UDF Threads:Pseudo-Hash: Binary Trees, Flat TablesFiles: Filter by Attribute, Tree List, Recursive Find, Recursive Folders Size, exported to XMLArrays: Nested, Pull Common Elements, Display 2dSystem: Expand Environment Strings, List Drives, List USB DrivesMisc: Multi-Layer Progress Bars, Binary FlagsStrings: Find Char(s) in String, Find String in SetOther UDF Threads I Participated:Base64 Conversions Link to comment Share on other sites More sharing options...
seandisanti Posted July 30, 2005 Author Share Posted July 30, 2005 It's a good function, I've got one something like that as well.But it looks like the OP was looking for a list of the occurances, not just the total count, which is why he's using an array.<{POST_SNAPBACK}>one thing that i made this for was for a file parse, by using it to check the delimiter, can instantly tell how many columns are needed to handle the info, and don't have to worry about ever trying to assign a value that doesn't exist...like on the timeclock program, it reads in the values to populate 8 labels from a text file, but only labels that had non default values at last unload would get new data... so rather than trying to assign non existent data to a variable, etc, can have it see that i have 5 delimiters, so only the first 6 get values... and i can use the array to clean up the stringMid that grabs the actual value...$value = StringMid($String,$blah[1] + 1, $blah[2] - ($blah[1] + 1))looks a little nicer than$value = StringMid($String,StringInStr($String,",") + 1,StringInString($String,",",2) - (StringInStr($String,",") + 1)) Link to comment Share on other sites More sharing options...
blindwig Posted August 1, 2005 Share Posted August 1, 2005 one thing that i made this for was for a file parse, by using it to check the delimiter, can instantly tell how many columns are needed to handle the info, and don't have to worry about ever trying to assign a value that doesn't exist...like on the timeclock program, it reads in the values to populate 8 labels from a text file, but only labels that had non default values at last unload would get new data... so rather than trying to assign non existent data to a variable, etc, can have it see that i have 5 delimiters, so only the first 6 get values... and i can use the array to clean up the stringMid that grabs the actual value...$value = StringMid($String,$blah[1] + 1, $blah[2] - ($blah[1] + 1))looks a little nicer than$value = StringMid($String,StringInStr($String,",") + 1,StringInString($String,",",2) - (StringInStr($String,",") + 1))<{POST_SNAPBACK}>Are you aware of the StringSplit() function? I think it will do what you're wanting to do. It takes a string, and splits it up into an array of substrings based on a specified delimter string (which is either a list of delimiters, or a big single delimiter). Check the helpfile for details. My UDF Threads:Pseudo-Hash: Binary Trees, Flat TablesFiles: Filter by Attribute, Tree List, Recursive Find, Recursive Folders Size, exported to XMLArrays: Nested, Pull Common Elements, Display 2dSystem: Expand Environment Strings, List Drives, List USB DrivesMisc: Multi-Layer Progress Bars, Binary FlagsStrings: Find Char(s) in String, Find String in SetOther UDF Threads I Participated:Base64 Conversions 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