8

I want to get the most frequent k-sized substring in a string. To achieve this, I'm using a table to store the number of occurrences for each substring. Here's the code:

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

The line counter[subs] = (counter[subs] and counter[subs] + 1 or 1) has the same mean of counter[subs] = (counter[subs] ? counter[subs]+1 : 1). This line would be only counter[subs] = counter[subs] + 1 if we could set every new counter element with 0. Is this possible in Lua? If not, what's the best way of doing something similar?

For instance, in Ruby, this is done by declaring a Hash like this:

counter = Hash.new(0)
hjpotter92
  • 78,589
  • 36
  • 144
  • 183
Fábio Perez
  • 23,850
  • 22
  • 76
  • 100

2 Answers2

9

You can set an __index metamethod in counter to return 0:

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

but this is easier and clearer:

counter[subs] = (counter[subs] or 0) + 1
lhf
  • 70,581
  • 9
  • 108
  • 149
0

For your case, lhf's solution is sufficient. Just for completeness, I would like to mention there is a more complex way, that enables some slightly more complex functionality. Specifically, it acts "as you would expect" when you use it with mutable values, such as table: it both creates the item, and assigns it to the key when created.

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
kazagistar
  • 1,537
  • 8
  • 20
  • You probably need `rawset` to avoid loops. – lhf Nov 07 '13 at 13:20
  • I am only using __index, which only is called if you are trying to get a value, and only if there is no item at that key in the table. I don't override the writing part, it works as normal. – kazagistar Nov 07 '13 at 23:14