Mô đun:Road data/util
Giao diện
local util = {}local insert = table.insertlocal concat = table.concatlocal format = mw.ustring.format----- Add all entries in `arr` into `target`.-- An error is raised if `overwrite` is not true-- and any key in `arr` is already in `target`.function util.addAll(target, arr, overwrite) if type(target) ~= "table" then error("target không phải là một bảng") end for key,value in pairs(arr) do if overwrite or target[key] == nil then target[key] = value else error("Từ khóa trùng lặp: " .. tostring(key)) end endendlocal function comp(e1, e2) local t1 = type(e1) local t2 = type(e2) if t1 ~= t2 then return t1 < t2 end if t1 == "function" then error("Loại function không mong đợi") end return e1 < e2endlocal arrayToStringAuxarrayToStringAux = function(arr, indent) if type(arr) ~= "table" then error("arr không phải là một bảng") end if type(indent) ~= "number" then error("indent không phải là một số") end local result = {} local keys = {} for key in pairs(arr) do insert(keys, key) end table.sort(keys, comp) for _,key in ipairs(keys) do local value = arr[key] local keyPrint if type(key) == "string" then keyPrint = format("\"%s\"", key) else keyPrint = tostring(key) end local valuePrint if type(value) == "table" then valuePrint = format("{\n%s\n%s}", arrayToStringAux(value, indent + 4), string.rep(" ", indent)) elseif type(value) == "string" then valuePrint = format("\"%s\"", value) else valuePrint = tostring(value) end insert(result, format("%s[%s] = %s", string.rep(" ", indent), keyPrint, valuePrint)) end return concat(result, ", \n")end--- Return a string representation of `arr`.function util.arrayToString(arr, indent) return arrayToStringAux(arr, indent or 0)endlocal function convert(distance, multiplier, desiredPrec) if type(distance) ~= "string" then error("distance không phải là một chuỗi") end if type(multiplier) ~= "number" then error("multiplier không phải là một số") end -- Import math functions. local math = require "Mô đun:Math" -- This function returns the precision of a given string representing a number. local precision = math._precision -- This function returns the order of magnitude of a given string representing a number. local order = math._order -- This function rounds a given number to the given number of digits. local round = math._precision_format local prec = desiredPrec or precision(distance) if not desiredPrec then local ord = order(distance) -- Adjust precision based on multiplier, as done in {{convert}}. prec = prec - order(multiplier / 0.2) end local converted = distance * multiplier local magnitude = order(converted) if prec <= -magnitude then -- Ensure the result has at least two significant digits. prec = -magnitude + 1 end return round(converted, prec)end--[[-Convert length specified in one unit (mi or km) to length in the other unit.@param #map<#string, #string> lengths a map from unit to distance (as a string) in that unit; may contain entry `prec` indicating desired conversion precision@param #string blank text to be used if length is unspecified@return #table a table containing the conversion result: orig = source unit; comp = target unit; mi = length in miles; ft = converted length in feet; km = length in kilometers; m = converted length in meters; error = error message, if any]]function util.convertLengths(lengths, blank) -- Import math functions. local math = require "Mô đun:Math" -- In Lua, storing functions locally results in more efficient execution. -- This function rounds a given number to the given number of digits. local round = math._precision_format -- This function returns the precision of a given string representing a number. local precision = math._precision local kmPerMile = 1.609344 local ftPerMile = 5280 -- The length in kilometers as passed to the function. local km = lengths.km -- The length in miles as passed to the function. local mi = lengths.mi -- Precision for the converted length. local prec = lengths.prec local errMsg = {} -- Sanitize inputs. local km_ = tonumber(km) if km and not km_ then insert(errMsg, util.err("km không phải là một số")) end local mi_ = tonumber(mi) if mi and not mi_ then insert(errMsg, util.err("mi không phải là một số")) end local prec_ = tonumber(prec) if prec and not prec_ then insert(errMsg, util.err("prec không phải là một số")) end prec = prec_ local ft local m local orig = "mi" local comp = "km" if mi and km then insert(errMsg, util.err("Cả hai mi và km đều được xác định")) elseif mi then -- Length in miles was passed. if mi_ then -- If `mi` is indeed a number, compute and round the length in kilometers. km = convert(mi, kmPerMile, prec) m = convert(mi, kmPerMile * 1000, prec) -- format mi (insert separators as in 1,000) mi = round(mi_, precision(mi)) else -- `mi` is not a number. km = blank m = blank end elseif km then -- Length in kilometers was passed. -- Swap units. orig, comp = comp, orig if km_ then -- If `km` is indeed a number, compute and round the length in miles. mi = convert(km, 1 / kmPerMile, prec) ft = convert(km, ftPerMile / kmPerMile, prec) -- format km (insert separators as in 1,000) km = round(km_, precision(km)) else -- `km` is not a number. mi = blank ft = blank end else mi = blank ft = blank km = blank m = blank end local error = concat(errMsg) if error == "" then error = nil end return {mi = mi, ft = ft, km = km, m = m, orig = orig, comp = comp, error = error}end--- Generates wikitext error messages.function util.err(msg) if msg == nil then error("Thông báo lỗi không xác định") end return format('<strong class="error">Lỗi: %s</strong>', msg)endreturn util