Module:ArrayList
local p = {}
-- Helper function to trim whitespace
local function trim(s)
return s:match("^%s*(.-)%s*$")
end
-- Escape special characters in the delimiter for pattern matching
local function escapePattern(str)
return str:gsub("([%^%$%(%)%%%.%[%]%*%+%?%-])", "%%%1")
end
-- Main function to call other functions dynamically
function p.main(frame)
local func = frame.args[1]
if p[func] then
return p[func](frame)
else
return "void:notfound " .. tostring(func)
end
end
-- Count occurrences of delimiter in a string
function p.count(frame)
local str = frame.args[2] or ""
local delimiter = frame.args[3] or ","
local nostrip = frame.args["nostrip"]
delimiter = escapePattern(delimiter)
-- If nostrip is not set to "true", strip leading/trailing delimiters
if nostrip ~= "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)
end
local count = select(2, str:gsub(delimiter, ""))
return count + 1
end
-- Get the Nth item in a delimited string, supporting negative indices
function p.get(frame)
local str = frame.args[2] or ""
local delimiter = frame.args[3] or ","
local index = frame.args[4]
delimiter = escapePattern(delimiter)
str = str:gsub("^%s*" .. delimiter .. "%s*(.-)%s*" .. delimiter .. "$", "%1")
local items = {}
for item in string.gmatch(str, "([^" .. delimiter .. "]+)") do
table.insert(items, trim(item))
end
if index == "last" then
index = #items
elseif index and tonumber(index) then
index = tonumber(index)
if index < 0 then
index = #items + index + 1
end
else
return "void:invalid"
end
return items[index] or "void:outrange"
end
-- Find the position of the Nth occurrence of a matching item in a delimited string
function p.pos(frame)
local str = frame.args[2] or ""
local delimiter = frame.args[3] or ","
local item = frame.args[4] or ""
local occurrence = tonumber(frame.args[5])
delimiter = escapePattern(delimiter)
str = str:gsub("^%s*" .. delimiter .. "%s*(.-)%s*" .. delimiter .. "$", "%1")
local positions = {}
local index = 1
for subitem in string.gmatch(str, "([^" .. delimiter .. "]+)") do
subitem = trim(subitem)
if subitem == item then
table.insert(positions, index)
end
index = index + 1
end
if not occurrence then
return #positions > 0 and table.concat(positions, ",") or "void:nomatch"
else
return positions[occurrence] or -1
end
end
-- Perform mathematical operations on numeric array items
function p.math(frame)
local str = frame.args[2] or ""
local delimiter = frame.args[3] or ","
local operation = frame.args[4]
delimiter = escapePattern(delimiter)
str = str:gsub("^%s*" .. delimiter .. "%s*(.-)%s*" .. delimiter .. "$", "%1")
local items = {}
for item in string.gmatch(str, "([^" .. delimiter .. "]+)") do
local number = tonumber(trim(item))
if number then
table.insert(items, number)
else
return "void:isalpha"
end
end
if #items == 0 then
return "void:nonumeric"
elseif operation == "sum" then
local total = 0
for _, num in ipairs(items) do
total = total + num
end
return total
elseif operation == "min" or operation == "max" then
local extreme = items[1]
local comparison = operation == "min" and function(a, b) return a < b end or function(a, b) return a > b end
for _, num in ipairs(items) do
if comparison(num, extreme) then
extreme = num
end
end
return extreme
else
return "void:unsupported"
end
end
-- Sorts array with options for reverse ("r") and alpha-first ("a").
function p.sort(frame)
local str = frame.args[2] or ""
local delimiter = frame.args[3] or ","
local params = frame.args[4] or ""
local delim_pat = escapePattern(delimiter)
-- Determine sort options (check if params a or r expressed)
local reverse = params:find("r") and true or false
local alpha_priority = params:find("a") and true or false
local items = {}
local orig_index = 1
-- Split string using delimiter.
for item in string.gmatch(str, "([^" .. delim_pat .. "]+)") do
item = item:match("^%s*(.-)%s*$") -- trim whitespace
local num = tonumber(item)
local isnum = (num ~= nil)
local isalpha = (not isnum and item:match("^[A-Za-z]+$")) and true or false
local group
if alpha_priority then
if isalpha then
group = 1
elseif isnum then
group = 2
else
group = 3
end
else
if isnum then
group = 1
elseif isalpha then
group = 2
else
group = 3
end
end
table.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 + 1
end
table.sort(items, function(a, b)
-- compare groups
if a.group ~= b.group then
return a.group < b.group
end
-- if both items in same group, decide
-- comparison based on alpha_priority flag
if alpha_priority then
-- if letters come first, group 1 = letters
if a.group == 1 then -- Both are alphabetic.
return a.raw:lower() < b.raw:lower()
elseif a.group == 2 then -- Both are numeric.
return a.num < b.num
else -- Group 3: special items.
return a.orig < b.orig
end
else
-- if numbers first, group 1 = numbers
if a.group == 1 then -- Both are numeric.
return a.num < b.num
elseif a.group == 2 then -- Both are alphabetic.
return a.raw:lower() < b.raw:lower()
else -- Group 3: special items.
return a.orig < b.orig
end
end
end)
-- Reverse order if requested
if reverse then
for i = 1, math.floor(#items / 2) do
items[i], items[#items - i + 1] = items[#items - i + 1], items[i]
end
end
-- Build output string
local output = {}
for _, v in ipairs(items) do
table.insert(output, v.raw)
end
return table.concat(output, delimiter)
end
return p
Content Disclaimer
Informasi ini disarikan dari Wikipedia dan disajikan kembali untuk tujuan edukasi. Konten tersedia di bawah lisensi CC BY-SA 3.0. Kami tidak bertanggung jawab atas ketidakakuratan data yang bersumber dari kontribusi publik tersebut.
- The information displayed on this website is sourced in part or in whole from Wikipedia and has been adapted for the purpose of restating it. We strive to provide accurate and relevant information, however:
- There is no guarantee of absolute accuracy. Wikipedia is an open, collaborative project that can be edited by anyone, so information is subject to change.
- It is not intended to constitute professional advice. The content displayed is for informational and educational purposes only. For important decisions (e.g., medical, legal, or financial), please consult a professional.
- Content copyright. Wikipedia is licensed under the Creative Commons Attribution-ShareAlike License (CC BY-SA). This means that content may be reused with appropriate attribution and shared under a similar license.
- Responsible use. Any risk arising from the use of information from this website is entirely the responsibility of the user.