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. Възможно ли е това в Lua? Ако не, какъв е най-добрият начин да направите нещо подобно?

Например в Ruby това се прави чрез деклариране на хеш по следния начин:

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