if Var in MatchList if Var not in MatchList if Var contains MatchList if Var not contains MatchListWith new user functions we can provide tools for manipulating these comma delimited lists. In the script below I tried to strike a balance between code length and running time. I tested them for function, but there still could be some bugs in it.
ListAdd(item,pos,ByRef list) ; Add item to the list at pos, < 0 counted from the end { ; ErrorLevel = 1 if pos was truncated, = 0 otherwise _list_ = ,%list%, ; enclose in commas for search IfLess pos,0, { ; pos = -1,-2... counted from right _pos := -pos StringGetPos chpos, _list_, `,, R%_pos% } Else IfGreater pos,1, { ; pos = 2,3... counted from left StringGetPos chpos, _list_, `,, L%pos% IfEqual chpos,-1, StringLen chpos, _list_ } ; pos = 0, 1 and normal cases ... StringLeft leftlist, list, % chpos - 1 StringTrimLeft rightlist, list, %chpos% IfNotEqual rightlist,, SetEnv item, %item%`, IfNotEqual leftlist,, SetEnv item, `,%item% list = %leftlist%%item%%rightlist% } ListCut(pos, ByRef list) ; Remove & return item from list at pos, < 0 from end { _list_ = ,%list%, ; enclose in commas for search Transform p1, ABS, pos p2 := p1 + 1 IfGreater pos,-1, { ; pos > 0 counted from left, pos = 0: empty StringGetPos ch1, _list_, `,, L%p1% StringGetPos ch2, _list_, `,, L%p2% } Else IfLess pos,0, { ; pos < 0 counted from right StringGetPos ch2, _list_, `,, R%p1% StringGetPos ch1, _list_, `,, R%p2% } IfGreater ErrorLevel,0, Return ; nothing found StringMid item, list, ch1+1, ch2-ch1-1 StringLeft leftlist, list, % ch1 - 1 StringTrimLeft rightlist, list, %ch2% IfEqual rightlist,, SetEnv list, %leftlist% Else IfEqual leftlist,, SetEnv list,%rightlist% Else SetEnv list, %leftlist%,%rightlist% Return %item% } ListItem(pos,list) ; Return item at pos, < 0 from the end { _list_ = ,%list%, ; enclose in commas for search Transform p1, ABS, pos p2 := p1 + 1 IfGreater pos,-1, { ; pos > 0 counted from left, pos = 0: empty StringGetPos ch1, _list_, `,, L%p1% StringGetPos ch2, _list_, `,, L%p2% } Else IfLess pos,0, { ; pos < 0 counted from right StringGetPos ch2, _list_, `,, R%p1% StringGetPos ch1, _list_, `,, R%p2% } IfGreater ErrorLevel,0, Return ; nothing found StringMid item, list, ch1+1, ch2-ch1-1 Return %item% } ListPos(item,list) ; Return position of 1st copy of item, 0 if not found { _list_ = ,%list%, ; enclose in commas for search StringGetPos ch, _list_, `,%item%`, StringLeft list, _list_, % ch+1 StringReplace list, list, `,, `,, UseErrorLevel Return %ErrorLevel% } ListReplace(itm1,itm2,ByRef list) ; Replace all itm1 with itm2 in list, itm2="": delete { ; ErrorLevel = # items replaced list = ,%list%, ; enclose in commas for search _it_ = ,%itm2%, IfEqual itm2,, SetEnv _it_, `, Loop { ; StringReplace does not delete consecutive items StringReplace list, list, `,%itm1%`,, %_it_%, UseErrorLevel IfEqual ErrorLevel,0, Break cnt += ErrorLevel } ErrorLevel := cnt StringTrimLeft list, list, 1 StringTrimRight list, list, 1 }Split or merge of lists is easy, you don't need functions for them. As the need arises I will add more functions, like sort, or removing duplicates. Any ideas, what else could be useful?
Edit 2006.02.25. The full version is here. There is also an experimental version. It uses the global variable "_" to store the list separator, which can be set to any character, like "_ = `;".
Edit 2006.03.17. Minor bugfix, version 1.5/1.51 uploaded
Edit 2008.12.19. Source moved to AutoHotkey.net