Модуль:GetField: различия между версиями
Pok (обсуждение | вклад) Нет описания правки |
Pok (обсуждение | вклад) Нет описания правки |
||
| (не показаны 2 промежуточные версии этого же участника) | |||
| Строка 285: | Строка 285: | ||
end | end | ||
return true | return true | ||
end | end | ||
| Строка 629: | Строка 612: | ||
local value = get_by_path(entry, keyPath) | local value = get_by_path(entry, keyPath) | ||
return format_value(value) | return format_value(value) | ||
end | |||
local function collect_by_parsed_path(tbl, parsedPath, pos, out) | |||
if pos > #parsedPath then | |||
out[#out + 1] = tbl | |||
return | |||
end | |||
if type(tbl) ~= "table" then | |||
return | |||
end | |||
local token = parsedPath[pos] | |||
local key = token[1] | |||
local idx = token[2] | |||
if key == "*" then | |||
for _, child in pairs(tbl) do | |||
local nextCur = child | |||
if idx then | |||
if type(nextCur) ~= "table" then | |||
nextCur = nil | |||
else | |||
nextCur = nextCur[idx] | |||
end | |||
end | |||
collect_by_parsed_path(nextCur, parsedPath, pos + 1, out) | |||
end | |||
return | |||
end | |||
local nextCur | |||
if key and key ~= "" then | |||
nextCur = tbl[key] | |||
if nextCur == nil then | |||
nextCur = tbl["!type:" .. key] | |||
end | |||
else | |||
nextCur = tbl | |||
end | |||
if idx then | |||
if type(nextCur) ~= "table" then | |||
return | |||
end | |||
nextCur = nextCur[idx] | |||
end | |||
collect_by_parsed_path(nextCur, parsedPath, pos + 1, out) | |||
end | |||
local function get_by_parsed_path_multi(tbl, parsedPath) | |||
local out = {} | |||
collect_by_parsed_path(tbl, parsedPath, 1, out) | |||
return out | |||
end | |||
local function entry_matches_path(entry, parsedPath, searchValue, searchType) | |||
local values = get_by_parsed_path_multi(entry, parsedPath) | |||
local target = tostring(searchValue) | |||
for _, v in ipairs(values) do | |||
if searchType == "key" then | |||
if type(v) == "table" and v[target] ~= nil then | |||
return true | |||
end | |||
else | |||
if contains_target(v, target) then | |||
return true | |||
end | |||
end | |||
end | |||
return false | |||
end | |||
local function entry_has_any_nonempty_path(entry, parsedPath) | |||
local values = get_by_parsed_path_multi(entry, parsedPath) | |||
for _, v in ipairs(values) do | |||
if is_nonempty_value(v) then | |||
return true | |||
end | |||
end | |||
return false | |||
end | end | ||
| Строка 656: | Строка 728: | ||
end | end | ||
local ids = collect_id_keys(data) | local ids = collect_id_keys(data) | ||
if #ids == 0 then | if #ids == 0 then | ||
| Строка 662: | Строка 733: | ||
end | end | ||
local matches | local matches = {} | ||
local target = tostring(searchValue) | |||
for _, idKey in ipairs(ids) do | |||
local entry = resolve_entry(data, idKey) | |||
if type(entry) == "table" and entry_matches_path(entry, parsedPath, target, searchType) then | |||
matches[#matches + 1] = idKey | |||
end | end | ||
end | end | ||
| Строка 745: | Строка 801: | ||
end | end | ||
local matches | local matches = {} | ||
if searchType == "path" then | if searchType == "path" then | ||
for _, idKey in ipairs(ids) do | for _, idKey in ipairs(ids) do | ||
local | local entry = resolve_entry(data, idKey) | ||
if | if type(entry) == "table" and entry_has_any_nonempty_path(entry, parsedPath) then | ||
matches[#matches + 1] = idKey | matches[#matches + 1] = idKey | ||
end | end | ||
end | end | ||
else | |||
local target = tostring(searchValue) | local target = tostring(searchValue) | ||
for _, idKey in ipairs(ids) do | for _, idKey in ipairs(ids) do | ||
local | local entry = resolve_entry(data, idKey) | ||
if type( | if type(entry) == "table" and entry_matches_path(entry, parsedPath, target, searchType) then | ||
matches[#matches + 1] = idKey | matches[#matches + 1] = idKey | ||
end | end | ||
end | end | ||