Module:ArrayList
Appearance
localp={}-- Helper function to trim whitespacelocalfunctiontrim(s)returns:match("^%s*(.-)%s*$")end-- Escape special characters in the delimiter for pattern matchinglocalfunctionescapePattern(str)returnstr:gsub("([%^%$%(%)%%%.%[%]%*%+%?%-])","%%%1")end-- Main function to call other functions dynamicallyfunctionp.main(frame)localfunc=frame.args[1]ifp[func]thenreturnp[func](frame)elsereturn"void:notfound "..tostring(func)endend-- Count occurrences of delimiter in a stringfunctionp.count(frame)localstr=frame.args[2]or""localdelimiter=frame.args[3]or","localnostrip=frame.args["nostrip"]delimiter=escapePattern(delimiter)-- If nostrip is not set to "true", strip leading/trailing delimitersifnostrip~="true"then-- Remove leading and trailing delimiters (along with any surrounding whitespace)str=str:gsub("^%s*"..delimiter.."%s*",""):gsub("%s*"..delimiter.."%s*$","")-- Normalize internal consecutive delimiters to a single delimiter (replace ",," with ",")str=str:gsub("%s*"..delimiter.."%s*"..delimiter.."%s*",delimiter)endlocalcount=select(2,str:gsub(delimiter,""))returncount+1end-- Get the Nth item in a delimited string, supporting negative indicesfunctionp.get(frame)localstr=frame.args[2]or""localdelimiter=frame.args[3]or","localindex=frame.args[4]delimiter=escapePattern(delimiter)str=str:gsub("^%s*"..delimiter.."%s*(.-)%s*"..delimiter.."$","%1")localitems={}foriteminstring.gmatch(str,"([^"..delimiter.."]+)")dotable.insert(items,trim(item))endifindex=="last"thenindex=#itemselseifindexandtonumber(index)thenindex=tonumber(index)ifindex<0thenindex=#items+index+1endelsereturn"void:invalid"endreturnitems[index]or"void:outrange"end-- Find the position of the Nth occurrence of a matching item in a delimited stringfunctionp.pos(frame)localstr=frame.args[2]or""localdelimiter=frame.args[3]or","localitem=frame.args[4]or""localoccurrence=tonumber(frame.args[5])delimiter=escapePattern(delimiter)str=str:gsub("^%s*"..delimiter.."%s*(.-)%s*"..delimiter.."$","%1")localpositions={}localindex=1forsubiteminstring.gmatch(str,"([^"..delimiter.."]+)")dosubitem=trim(subitem)ifsubitem==itemthentable.insert(positions,index)endindex=index+1endifnotoccurrencethenreturn#positions>0andtable.concat(positions,",")or"void:nomatch"elsereturnpositions[occurrence]or-1endend-- Perform mathematical operations on numeric array itemsfunctionp.math(frame)localstr=frame.args[2]or""localdelimiter=frame.args[3]or","localoperation=frame.args[4]delimiter=escapePattern(delimiter)str=str:gsub("^%s*"..delimiter.."%s*(.-)%s*"..delimiter.."$","%1")localitems={}foriteminstring.gmatch(str,"([^"..delimiter.."]+)")dolocalnumber=tonumber(trim(item))ifnumberthentable.insert(items,number)elsereturn"void:isalpha"endendif#items==0thenreturn"void:nonumeric"elseifoperation=="sum"thenlocaltotal=0for_,numinipairs(items)dototal=total+numendreturntotalelseifoperation=="min"oroperation=="max"thenlocalextreme=items[1]localcomparison=operation=="min"andfunction(a,b)returna<bendorfunction(a,b)returna>bendfor_,numinipairs(items)doifcomparison(num,extreme)thenextreme=numendendreturnextremeelsereturn"void:unsupported"endend-- Sorts array with options for reverse ("r") and alpha-first ("a").functionp.sort(frame)localstr=frame.args[2]or""localdelimiter=frame.args[3]or","localparams=frame.args[4]or""localdelim_pat=escapePattern(delimiter)-- Determine sort options (check if params a or r expressed)localreverse=params:find("r")andtrueorfalselocalalpha_priority=params:find("a")andtrueorfalselocalitems={}localorig_index=1-- Split string using delimiter.foriteminstring.gmatch(str,"([^"..delim_pat.."]+)")doitem=item:match("^%s*(.-)%s*$")-- trim whitespacelocalnum=tonumber(item)localisnum=(num~=nil)localisalpha=(notisnumanditem:match("^[A-Za-z]+$"))andtrueorfalselocalgroupifalpha_prioritythenifisalphathengroup=1elseifisnumthengroup=2elsegroup=3endelseifisnumthengroup=1elseifisalphathengroup=2elsegroup=3endendtable.insert(items,{raw=item,num=num,isnum=isnum,isalpha=isalpha,group=group,orig=orig_index-- remember original order for special items})orig_index=orig_index+1endtable.sort(items,function(a,b)-- compare groupsifa.group~=b.groupthenreturna.group<b.groupend-- if both items in same group, decide-- comparison based on alpha_priority flagifalpha_prioritythen-- if letters come first, group 1 = lettersifa.group==1then-- Both are alphabetic.returna.raw:lower()<b.raw:lower()elseifa.group==2then-- Both are numeric.returna.num<b.numelse-- Group 3: special items.returna.orig<b.origendelse-- if numbers first, group 1 = numbersifa.group==1then-- Both are numeric.returna.num<b.numelseifa.group==2then-- Both are alphabetic.returna.raw:lower()<b.raw:lower()else-- Group 3: special items.returna.orig<b.origendendend)-- Reverse order if requestedifreversethenfori=1,math.floor(#items/2)doitems[i],items[#items-i+1]=items[#items-i+1],items[i]endend-- Build output stringlocaloutput={}for_,vinipairs(items)dotable.insert(output,v.raw)endreturntable.concat(output,delimiter)endreturnp