Posted 24 January 2014 - 12:44 AM
Hi!
I recently played with algorithmics and iterators and made an API to walk through trees. Not actual trees of course, but trees like genealogic trees. For example, a table can be seen as a tree, as well as folders. Take a look there for further explanation.
tree API on pastebin : http://pastebin.com/ZFaWd9iH
With few coding, you can now walk through (=enumerate any node) any tree shaped structure.
tree.explistGen
returns a pairs-like function, ie a function which, when applied to a tree, returns an "explist", which actually is a 3-uple of "iterator, base, initial element".
the first returned value is used for the walk, due to the way iterator work, so type
other example : subDir : list any sub directories of one folder.
let say you have a folder "myhelp" with help documentation and want to have subdirectories, for readability, and you want to add the several paths to the help directories. Then just type :
tree.explistGenOpt
Just in case you want put the option into the pairs-like function.
example :
The three other functions (tree.itNodes, tree.itInodes, tree.itLeaves) of the API are iterator generators (iterator = next-like function) :
Hope you enjoyed. Tell me if you want more examples like subDir
I recently played with algorithmics and iterators and made an API to walk through trees. Not actual trees of course, but trees like genealogic trees. For example, a table can be seen as a tree, as well as folders. Take a look there for further explanation.
tree API on pastebin : http://pastebin.com/ZFaWd9iH
With few coding, you can now walk through (=enumerate any node) any tree shaped structure.
tree.explistGen
Spoiler
syntax :
subValues = tree.explistGen(fSons, [isInode, [option]])
for _,v in subValues(root, order) do
doStuff()
end
returns a pairs-like function, ie a function which, when applied to a tree, returns an "explist", which actually is a 3-uple of "iterator, base, initial element".
- fSons must be a function that takes an internal node of the tree, and rreturns the list (table, numerical or not, keys don't matter) of its sons.
- optional isInode is a function that tells wether a node is internal or not (may have children). Necessary when fSons errors on non internal nodes, or do not returns an empty table
- option is either "nodes", "inodes" or "leaves". On "inodes", the iterator will only return the internal nodes, on "leaves", the terminal nodes. Default : "nodes".
- order is either "pre", "post" or "bfs", which stands for pre-order, post-order and level-order (breadth-first search), that are the order of the walk (ref). Default : "pre"
local fSons = function (t)
return t
-- a table is already the set of its sons.
end
local isInode = function(t)
-- necessary since fSons does not return a table when called on leaves.
return type(t) == "table"
end
subValues = tree.explistGen(fSons, isInode)
Warning : the code above infinite loop on auto referring tables (could be fixed with a better fSons)the first returned value is used for the walk, due to the way iterator work, so type
for _,v in subValues(myTable) do
...
end
(or anything that you won't use, "_" is just a convention)other example : subDir : list any sub directories of one folder.
local fSons = function (sPath)
--nodes are absolute path (strings)
local tSons = fs.list(sPath)
for k,v in pairs(tSons) do
tSons[k] = s..tSons[k]
end
-- I just transformed local into absolute
return tSons
end
--isInode could have been useless, since [url="http://computercraft.info/wiki/Fs.list"]fs.list works consistantly on files[/url], however, we need it to enumerate only directories. What we need is exactly fs.isDir()
subDir = tree.explistGen(fSons, fs.isDir, "inode")
let say you have a folder "myhelp" with help documentation and want to have subdirectories, for readability, and you want to add the several paths to the help directories. Then just type :
for _,sPath in subDir("/myhelp") do
help.setPath(help.path()..":"..sPath)
end
tree.explistGenOpt
Spoiler
syntax :
subValues = tree.explistGenOpt(fSons, [isInode])
for _,v in subValues(root, [order],[opt]) do
doStuff()
end
Just in case you want put the option into the pairs-like function.
example :
local fSons = function (sPath)
local tSons = fs.list(sPath)
for k,v in pairs(tSons) do
tSons[k] = s..tSons[k]
end
return tSons
end
subFiles_Folders = tree.explistGenOpt(fSons, fs.isDir)
then
for _,sPath in subFiles_Folders("/myhelp", nil,"inode") do
<block>
end
is equivalent to the previous
for _,sPath in subDir ("/myhelp") do
<block>
end
The three other functions (tree.itNodes, tree.itInodes, tree.itLeaves) of the API are iterator generators (iterator = next-like function) :
Spoiler
(explistGen (fSons, fIsInode, "nodes"))(t,order)
is (almost) the same as
itNodes(fSons, fIsInode), order, {t}
Hope you enjoyed. Tell me if you want more examples like subDir
Edited on 23 January 2014 - 11:45 PM