#!/usr/bin/luaThe preceding program produces the following output:
sf=string.format
tab = {"one", "two", "three", fname="Steve", lname="Litt"}
tab[5] = "five"
local i
print("DO ALL DEFINED CONSECUTIVE INTEGER KEYS STARTING FROM 1")
i = 1
while tab[i] do
print(sf("i=%s, v=%s", tostring(i), tostring(tab[i])))
i=i+1
end
print("\nDO ALL CONSECUTIVE INTEGER KEYS FROM 1 TO #tab")
i = 1
while i <= #tab do
print(sf("i=%s, v=%s", tostring(i), tostring(tab[i])))
i=i+1
end
print("\nDO ALL INTEGER KEYS STARTING FROM 1, EVEN IF VALUES ARE NIL")
i = 1
while i <= table.maxn(tab) do
print(sf("i=%s, v=%s", tostring(i), tostring(tab[i])))
i=i+1
end
print("\nDO ALL KEYS, INTEGER OR OTHERWISE, WITH NON-NIL VALUES")
print("NOTE: THE ORDER THEY COME OUT IS UNDEFINED!!!")
local k, v
k, v = next(tab, nil)
while k do
print(sf("k=%s, v=%s", tostring(k), tostring(v)))
k, v = next(tab, k)
end
slitt@mydesk:~$ ./test.luaFour loops, four lessons. The first loop started at index 1 (numbering in Lua starts at 1, not 0), and kept running until it hit a key whose value was nil, which was key 4. So it printed the keys and values of the first three integer keys.
DO ALL CONSECUTIVE INTEGER KEYS STARTING FROM 1
i=1, v=one
i=2, v=two
i=3, v=three
DO ALL CONSECUTIVE INTEGER KEYS STARTING FROM 1 WITH #
i=1, v=one
i=2, v=two
i=3, v=three
DO ALL INTEGER KEYS STARTING FROM 1, EVEN IF VALUES ARE NIL
i=1, v=one
i=2, v=two
i=3, v=three
i=4, v=nil
i=5, v=five
DO ALL KEYS, INTEGER OR OTHERWISE, WITH NON-NIL VALUES
NOTE: THE ORDER THEY COME OUT IS UNDEFINED!!!
k=1, v=one
k=2, v=two
k=3, v=three
k=fname, v=Steve
k=lname, v=Litt
k=5, v=five
slitt@mydesk:~$
#!/usr/bin/luaThe output is the same as those for the while loops discussed earlier:
sf=string.format
tab = {"one", "two", "three", fname="Steve", lname="Litt"}
tab[5] = "five"
local i
print("DO ALL CONSECUTIVE INTEGER KEYS STARTING FROM 1")
i = 1
repeat
if tab[i] then print(sf("i=%s, v=%s", tostring(i), tostring(tab[i]))) end
i=i+1
until not tab[i]
print("\nDO ALL CONSECUTIVE INTEGER KEYS STARTING FROM 1 WITH #")
i = 0
repeat
i=i+1
if i <= #tab then print(sf("i=%s, v=%s", tostring(i), tostring(tab[i]))) end
until i > #tab
print("\nDO ALL INTEGER KEYS STARTING FROM 1, EVEN IF VALUES ARE NIL")
i = 0
repeat
i=i+1
if i <= table.maxn(tab) then
print(sf("i=%s, v=%s", tostring(i), tostring(tab[i])))
end
until i >= table.maxn(tab)
print("\nDO ALL KEYS, INTEGER OR OTHERWISE, WITH NON-NIL VALUES")
print("NOTE: THE ORDER THEY COME OUT IS UNDEFINED!!!")
local k, v
k = nil
repeat
k, v = next(tab, k)
if v then print(sf("k=%s, v=%s", tostring(k), tostring(v))) end
until not k
slitt@mydesk:~$ ./test.luaDid you notice how contrived the preceding repeat-until loops were? Because it iterates at least one, we need to make sure that if there are no elements to iterate, no print happens. That's the reason for all the if statements.
DO ALL CONSECUTIVE INTEGER KEYS STARTING FROM 1
i=1, v=one
i=2, v=two
i=3, v=three
DO ALL CONSECUTIVE INTEGER KEYS STARTING FROM 1 WITH #
i=1, v=one
i=2, v=two
i=3, v=three
DO ALL INTEGER KEYS STARTING FROM 1, EVEN IF VALUES ARE NIL
i=1, v=one
i=2, v=two
i=3, v=three
i=4, v=nil
i=5, v=five
DO ALL KEYS, INTEGER OR OTHERWISE, WITH NON-NIL VALUES
NOTE: THE ORDER THEY COME OUT IS UNDEFINED!!!
k=1, v=one
k=2, v=two
k=3, v=three
k=fname, v=Steve
k=lname, v=Litt
k=5, v=five
slitt@mydesk:~$
#!/usr/bin/luaThis is a perfect use for a repeat-until loop because you want to go through it one, and hopefully only one time. But if necessary, if by chance the randomly selected filename already exists, it randomly selects another, and another, until it finds one that doesn't exist, and then opens it for write.
math.randomseed(os.time())
local handle
local fname
local done = false
repeat
fname = "yourfile" .. tostring(math.random(1,9) .. ".fil")
handle = io.open(fname, "r")
if handle then
io.close(handle);
io.write("Failed: ")
print(fname)
else
handle = io.open(fname, "w")
done=true
end
until done
io.write("SUCCEEDED: ")
print(fname)
print()
handle:write(fname)
handle:write("\n")
io.close(handle)
#!/usr/bin/lua
function open_temp_file()
local handle
local fname
while true do
fname = "yourfile" .. tostring(math.random(11111111,99999999) .. ".fil")
handle = io.open(fname, "r")
if not handle then
handle = io.open(fname, "w")
break
end
io.close(handle)
io.write(".") -- Shows collision, comment out except for diagnostics
end
return handle, fname
end
math.randomseed(os.time())
local i
for i=1, 50 do
local handle, fname = open_temp_file()
handle:write(fname)
handle:write("\n")
io.close(handle)
end
WARNING
The preceding program creates 50 files. DO NOT crank up the number of files very high, because if they become too numerous it becomes impossible to delete them with a simple wildcard command. DO NOT run this program in a directory with other files, because if you screw up a delete command you can wipe out needed files. BE CAREFUL with this program! |
for i=lowerlimit, upperlimit, step doHere's a list of Gotchas!
--stuff to be done
end
#!/usr/bin/luaThe preceding code produces the following:
sf=string.format
tab = {"one", "two", "three", fname="Steve", lname="Litt"}
tab[5] = "five"
local i
print("\nDO ALL CONSECUTIVE INTEGER KEYS STARTING FROM 1 WITH #")
i = 1
for i= 1, #tab do
print(sf("i=%s, v=%s", tostring(i), tostring(tab[i])))
end
print("\nDO ALL INTEGER KEYS STARTING FROM 1, EVEN IF VALUES ARE NIL")
for i=1, table.maxn(tab) do
print(sf("i=%s, v=%s", tostring(i), tostring(tab[i])))
end
slitt@mydesk:~$ ./test.luaNotice that for the two loop situations where you're counting to a known integer, the numeric for yields the cleanest code. It also yields the best performance.
DO ALL CONSECUTIVE INTEGER KEYS STARTING FROM 1 WITH #
i=1, v=one
i=2, v=two
i=3, v=three
DO ALL INTEGER KEYS STARTING FROM 1, EVEN IF VALUES ARE NIL
i=1, v=one
i=2, v=two
i=3, v=three
i=4, v=nil
i=5, v=five
slitt@mydesk:~$
#!/usr/bin/luaThe preceding creates a table with keys 1 through 4, 6 (skipping 5), float 1.5 and string "name". What it should do is iterate through keys 1 through 4, skipping 1.5 because 1.5 is not an integer, and stopping at 4 because 5 is undefined. It also doesn't iterate key "name" because it's a string, not an integer. So the preceding should print "one", "two", "three" and "four". Let's see if it does:
local mytable = {"one", "two", "three"}
mytable[4] = "four"
mytable[6] = "six" --notice the gap at 5
mytable["name"] = "Steve" --notice this is a string, not an integer
mytable[1.5] = "one-point-five" --notice this is a float, not integer
for k, v in ipairs(mytable) do
print(string.format("k=%s, v=%s",tostring(k),tostring(v)))
end
slitt@mydesk:/d/websites/tjunct/codecorn/lua$ ./test.luaThere it is -- ipairs() worked just as specified.
k=1, v=one
k=2, v=two
k=3, v=three
k=4, v=four
slitt@mydesk:/d/websites/tjunct/codecorn/lua$
slitt@mydesk:/d/websites/tjunct/codecorn/lua$ ./test.luaYou can see it printed every key and value. It just so happens the numeric keys were printed first and printed in order. DON'T COUNT ON THAT, IT WON'T ALWAYS WORK!!!
k=1, v=one
k=2, v=two
k=3, v=three
k=4, v=four
k=6, v=six
k=name, v=Steve
k=1.5, v=one-point-five
slitt@mydesk:/d/websites/tjunct/codecorn/lua$
[ Troubleshooters.com| Code Corner | Email Steve Litt ]
Copyright
(C) 2011 by Steve Litt --Legal