模块:Random list

来自Local Chinese Wikipedia
跳转到导航 跳转到搜索

本模块可以从一个列表中随机抽取指定数量的项目,以点列(*)的形式展示。

如果您只需要从列表中选取一个项目,请使用Module:Rand(本模板亦是受到该模块启发而建)。

建议直接使用呼叫本模块的模板{{Random list}}。

使用方式[编辑]

{{#invoke:Random list|randitems|...}}

参数:

  • 1:必填。包含所有候选项目的原始文本。
  • count:选填。要回传的项目数量。默认为 1。
    • 如果输入负数(如-1)或大于总项数,则回传所有项目。
  • 2:选填。自定义分隔符(Lua pattern)。
    • 指定后,模块会以 mw.text.split(text, sep) 分割第 1 参数。
    • 未指定时,模块不使用pattern分割,而是逐行解析wiki列表(以换行切分,并移除行首的*)。

示例[编辑]

随机从ABCD中抽取2个项目展示:

{{#invoke:Random list|randitems|count=2|
*選項A
*選項B
*選項C
*選項D
}}

效果:

  • 选项C
  • 选项D

使用独立页面[编辑]

Module:Rand一样,您也可以创建单独的页面,并嵌入到参数1

例如,若您使用

{{#invoke:Random list|randitems|count=2|{{User:Example/subpage}}}}

并在User:Example/subpage创建以下内容:

*選項A
*選項B
*選項C
*選項D

实现的效果是完全一致的。

参见[编辑]



require("strict")

local p = {}

-- 解析 wiki 列表(* 每行)
local function parse_wikilines(text)
    local items = {}
    for _, line in ipairs(mw.text.split(text, '\n')) do
        line = mw.text.trim(line)
        line = line:gsub('^%*%s*', '')
        if line ~= '' then
            table.insert(items, line)
        end
    end
    return items
end

-- 解析自訂分隔符(Lua pattern)
local function parse_by_separator(text, sep)
    local items = {}
    for _, part in ipairs(mw.text.split(text, sep)) do
        part = mw.text.trim(part)
        if part ~= '' then
            table.insert(items, part)
        end
    end
    return items
end

function p.randitems(frame)
    -- 1. 參數
    local text  = frame.args[1] or ''
    local count = tonumber(frame.args.count) or 1
    local sep   = frame.args[2]

    -- 2. 解析列表
    local items
    if sep and sep ~= '' then
        -- 自訂分隔符模式
        items = parse_by_separator(text, sep)
    else
        -- wiki 列表模式
        items = parse_wikilines(text)
    end

    local n = #items
    if n == 0 then return '' end
    if count < 0 then
        count = n
    elseif count < 1 then
        count = 1
    elseif count > n then
        count = n
    end

    -- 3. 隨機洗牌(頁面穩定)
    local seed = tonumber(mw.hash.hashValue(
        'md5',
        mw.title.getCurrentTitle().prefixedText
    ):sub(1, 8), 16)

    math.randomseed(seed + os.clock() * 100000)

    for i = n, 2, -1 do
        local j = math.random(i)
        items[i], items[j] = items[j], items[i]
    end

    -- 4. 輸出
    local result = {}
    for i = 1, count do
        result[#result + 1] = '* ' .. items[i]
    end

    return table.concat(result, '\n')
end

return p