Lua: установите для каждого нового элемента в таблице значение по умолчанию

Я хочу получить наиболее часто встречающуюся подстроку размера k в строке. Для этого я использую таблицу для хранения количества вхождений каждой подстроки. Вот код:

function frequentWords(seq, k)
  local subs = ""
  local counter = {}
  for i = 1,(seq:len()-k+1) do
    subs = seq:sub(i, i+k-1)
    counter[subs] = (counter[subs] and counter[subs] + 1 or 1)
    --print(subs .. ": " .. counter[subs])
  end
end

Строка counter[subs] = (counter[subs] and counter[subs] + 1 or 1) имеет то же среднее значение, что и counter[subs] = (counter[subs] ? counter[subs]+1 : 1). Эта строка была бы только counter[subs] = counter[subs] + 1, если бы мы могли установить каждый новый элемент counter с 0. Возможно ли это в Луа? Если нет, то как лучше всего сделать что-то подобное?

Например, в Ruby это делается путем объявления Hash следующим образом:

counter = Hash.new(0)

person Fábio Perez    schedule 05.11.2013    source источник


Ответы (2)


Вы можете установить метаметод __index в counter для возврата 0:

setmetatable(counter,{__index=function () return 0 end})

а так проще и понятнее:

counter[subs] = (counter[subs] or 0) + 1
person lhf    schedule 05.11.2013

Для вашего случая достаточно решения lhf. Просто для полноты картины я хотел бы упомянуть, что существует более сложный способ, который включает несколько более сложную функциональность. В частности, он действует «как и следовало ожидать», когда вы используете его с изменяемыми значениями, такими как таблица: он одновременно создает элемент и присваивает его ключу при создании.

function defaultTable(constructor)
  local new = {}
  local function initIndex(key)
    local value = constructor()
    new[key] = value
    return value
  end
  setmetatable(new, {__index=initIndex})
  return new
end
person kazagistar    schedule 05.11.2013
comment
Вероятно, вам нужно rawset, чтобы избежать циклов. - person lhf; 07.11.2013
comment
Я использую только __index, который вызывается только в том случае, если вы пытаетесь получить значение, и только если в таблице нет элемента с этим ключом. Я не переопределяю часть записи, она работает как обычно. - person kazagistar; 08.11.2013