I'm creating a function to check if a string is within one letter off of another string
function match(a, b) -- a is the 'correct' string -- b is the string I'm checking if it's within one letter off of a -- function will return true if it matches, else false end
example inputs/outputs:
match("sana", "sank") >> true
match("sana", "sana") >> true
match("sana", "sanan") >> true
match("sana", "ana") >> true
match("sana", "sanana") >> false, more than one letter off
match("sana", "sanaka") >> false
Well I can try to help somewhat.
First, we know that any string with less characters than #a - 1
or more characters than #a + 1
will always be more than one letter off. So we should start with something like this:
if #b > (#a + 1) or #b < (#a - 1) then return false end
If b
has more characters than a
, that means that a
must be somewhere within b
for it to still be true. In your examples, "sanan" is true while "sanka" is false. So this means that "sana", letter for letter, must be within b
, if b
is greater than a
.
Since b
is larger in this situation, string.match
much be applied to it instead of a
.
if #b > #a then return b:match(a) end
If b
has less characters than a
, we just need to do the opposite. b
must be inside a
, letter for letter.
if #b < #a then return a:match(b) end
The most difficult situation is when both a
and b
are equal. In this case, we're not looking for an exact match, all we need is a - 1
of the corresponding letters to be the same. Therefore for this we'll have to use a for loop.
if #a == #b then local matches = 0 for i = 1, #a do if a:sub(i, i) == b:sub(i, i) then matches = matches + 1 end end if matches >= #a - 1 then return true end end