Toggle menu
Toggle preferences menu
Toggle personal menu
Not logged in
Your IP address will be publicly visible if you make any edits.

Module:Cartesian with comma: Difference between revisions

From Ross Surname Project
m Redheadkelly moved page Module:Cartesian categories to Module:Cartesian with comma without leaving a redirect
 
m 1 revision imported
 
(No difference)

Latest revision as of 01:24, 21 October 2025

Documentation for this module may be created at Module:Cartesian with comma/doc

local remove, insert, concat = table.remove, table.insert, table.concat
local split, trim = mw.text.split, mw.text.trim
local clone = mw.clone

local function cartesian (sets)
    local product = {}
    local set = remove (sets)
    if #sets == 0 then
        for _, item in ipairs (set) do
            insert (product, { item })
        end
        return product
    end
    for __, first in ipairs (cartesian (sets)) do
        for _, second in ipairs (set) do
            insert (product, clone (first))
            insert (product [#product], second)
        end
    end
    return product
end

local function format_array (array, format, separator)
    local formatted = {}
    for _, combination in ipairs (array) do
        insert (formatted, format:format (unpack (combination)))
    end
    return concat (formatted, separator)
end
        
return {
combine = function (frame)
    local sets = {}
    local delimiter = frame.args.delimiter or ';'
    local splitter = '%s*' .. delimiter .. '%s*'
    local default_format = {}
    for i, list in ipairs (frame.args) do
        local items = split (trim (list), splitter)
        -- If this is the first set, add a comma to items that contain a comma
        if i == 1 then
            for j, item in ipairs(items) do
                if item:find(',') then
                    items[j] = item .. ','
                end
            end
        end
        sets[#sets + 1] = items
        insert (default_format, '%s')
    end
    local format = frame.args.format or concat (default_format, ', ')
    local separator = frame.args.separator or '\n'
    return format_array (cartesian (sets), format, separator)
end
}