lua-users home
lua-l archive

[Date Prev][Date Next][Thread Prev][Thread Next] [Date Index] [Thread Index]


Pete Kay wrote:
Hi,
I am write a price of code in Lua to break down phone number to country code, area code, and local code
For instance, 16502839332 -> 1      650    2839332
I have a series of country code, area code that I can match against. Previously with another language, I would do a comparision against each code to breakdown the number. With Lua, is there a more efficient way of doing this? I checked the String function in wiki and can't see anything. I know I can do a find and then sub to retrieve each code one by one, but I hope that there is a better way to do it.
Hi,

IMHO the best approach is to use a table of country codes indexed by length containing an areacode table also indexed by length.
Then you would check from the longest to the shortes codes.

Here is the algorithm with a sample code table: (area codes are not real ones exept for 43 Austria :-)
Code is not very well tested!!

local codes={
   [1]={
       ['1']={
           [1]={['3']=true,['4']=true,['5']=true},
           [2]={['32']=true,['24']=true,['25']=true},
           [3]={['321']=true,['212']=true},
       },
       ['7']={
           [1]={['1']=true,['2']=true,['3']=true},
           [3]={['112']=true,['223']=true},
       },
   },
   [2]={
       ['43']={
           [1]={['1']=true,['7']=true},
           [2]={['05']=true},
           [4]={['720']=true,['800']=true}
       },
   },
}

local table_maxn=table.maxn
local string_sub=string.sub

local function splitnumber(number)
   number=tostring(number) --ensure number is a string
for c=table_maxn(codes),1,-1 do --could be improoved with extra length table local countrycode=string_sub(number,1,c) --get possible countrycode from number
       if codes[c][countrycode] then --and check if the code exist
           local areacodes=codes[c][countrycode]
for b=table_maxn(areacodes),1,-1 do -- go trough all areacodes from the longest to shortest if areacodes[b] then --be sure ther are codes with that length local areacode=string_sub(number,c+1,c+b) --get possible areacode if areacodes[b][areacode] then --check existens and return splited number
                       return countrycode,areacode,string_sub(number,c+b+1)
                   end
               end
           end
           --return nil,"Areacode not found"
           return countrycode,"",string_sub(number,c+1)
       end
   end
   return nil,"Countrycode Not found"
end

--tests
print(splitnumber("430512345"))
print(splitnumber("1321987654"))
print(splitnumber("1322987654"))
print(splitnumber("1312987654"))
print(splitnumber("1198765432"))

I have also written a simple code loading function - Not tested at all! :-)

--requiers a filename to a csv file in the format "countrycode,areacode\n"
local string_match=string.match
local function loadcodes(filename)
   local codes={}
for line in io.lines(filename)
       local countrycode,areacode=string_match(line,"^(.-),(.-)")
       if not countrycode or not areacode then
           return nil,"Could not parese file"
       end
if codes[#countrycode]==nil then
           codes[#countrycode]={}
       end
       if codes[#countrycode][countrycode]==nil then
           codes[#countrycode][countrycode]={}
       end
       local country=codes[#countrycode][countrycode]
       if country[#areacode]==nil then
           country[#areacode]={}
       end
       country[#areacode][areacode]=true
   end
return codes
end


Best regards,
Michael