Модуль:Массив

Материал из Тептар — свободной энциклопедии
Перейти к навигации Перейти к поиску

Использование:

{{#invoke:Массив | iswitch
| value = значение, которому сопоставляются массивы из чисел
| 1 2 3..7 50..70 = 1, 2, 3-7, 50-70
| 9..40 = 9-40 (включительно)
| [41..48] = 41-48 (включительно)
| (80..100 = больше 80 (невключительно), но меньше 100 (включительно)
| (120..140) = 120-140 (невключительно)
| ..-2e9) = любое число, меньшее (но не равное) -2 000 000 000
| -2e9..0.75 = между -2 000 000 000 и 3/4 (включительно)
| 1e6.. = больше или равно 1 000 000
| default = Оставшиеся значения
}}

Примечание: результат при совпадении со значением нескольких перекрывающихся массивов непредсказуем, поэтому лучше не использовать такие массивы.


local function ranges( args )
    local value
    
    function inrange( v )
        if tonumber( v ) then return tonumber( v ) == value end -- simple number - just compare
        local lp, a, b, rp = v:match( '^([([]?)(.-)%.%.(.-)([)%]]?)$' ) -- a range
        local na, nb = tonumber( a ), tonumber( b )
        if  a ~= '' and not na -- both a and b must be either empty or a valid number
            or b ~= '' and not nb 
            or not ( na or nb ) -- at least one of na, nb must be a number
        then 
            error(string.format( 'Параметр задан неправильно: "%s" не является числом или массивом из чисел', v ), 0 )
            return false
        end 
        
        local llok = not na or na < value or lp ~= '(' and na == value 
        -- left-limit-ok: no ll or ll < value or ll == value and not open range
            
        local rlok = not nb or value < nb or rp ~= ')' and value == nb 
        -- right-limit-ok: no rl or value < rl or value == rl and not open range
        
        return llok and rlok
    end

    function match( s )
        if type( s ) == 'number' then return s == value end
        local res = false
        s:gsub("%S+", function( c ) res = res or inrange( c ) end)
        return res
    end
    
    value = tonumber( args.value )
    if not value then error('Значение параметра должно быть цифровым', 0) end
    for k, v in pairs( args ) do
        if k ~= 'value' and k~= 'default' and match( k ) then return v end
    end
    return args['default'] or ''
end

return { iswitch = function( frame ) return ranges( frame.args ) end, }