I am using a TCL list structure to mimic a hierarchical data structure.
That is, I have a list that consists of sub-lists, that in turn consist of
sub-lists, that in turn.... to about 5 levels deep. It is quite easy to
walk through the structure using "foreach" and "lindex", but I have now come
to a point where I need to either delete or replace one of the sub-list
elements (on the 5th level down).
Now, I know that I can delete or replace the element using "lreplace", but
how do I get the replacement to "propagate" itself back up through the list
structure to eventually reflect itself in the original upper-level list? I
seems that I could manually "lreplace" my way back up through the list
structure, but is there a cleaner way?
In other words, I start with the upper level list that I iterate over using
a "foreach" loop. Inside that loop, I use lindex to pick out parts of the
current list element. One of these "parts" is also a list, so I again use
"foreach" to iterate over it. This process happens over and over again
until I am 5 levels down from the original upper-level list. Now I have a
"copy" of the sub-list that I need to replace an element within, but
eventually, I need the replacement to happen in the original upper-level
list. Is there an easy to do this? As far as I know I cannot "lreplace"
this element in the upper-level list directly. It seems that I need to
replace it in the level 5 list. Then update level 4, level 3, level 2, and
level 1 in turn.
I'm not sure that I have explained this well, but hopefully you understand.
If there is not a simple way to do this, do I have a data structure design
problem? Is there a better way to store my data?
Any advice is appreciated.
Thanks,
Jeff Godfrey
Thanks,
Jeff Godfrey
Jeff Godfrey wrote in message ...
I know, advertisement is bad, but why don't you take a look at
ParseTools [1] ?
One of the tools it provides are commands to handle abstract syntax
trees. No nested lists, but an array whose values contains the keys of
other elements, thus representing the structure of the tree. Much
easier to manipulate and very easy to convert from/to nested lists.
[1] http://www.purl.org/NET/akupries/soft/ptools/
--
Sincerely,
Andreas Kupries <a.ku...@westend.com>
<http://www.purl.org/NET/akupries/>
<http://www.usenix.org/events/tcl2k/> You are coming too ?
-------------------------------------------------------------------------------
In situations like this, I typically store the individual "records" in an array
and implement the structure of the record with keylset/keylget from Extended Tcl
The point is that the record typically has a more or less fixed size, whereas
the table may grow indefinitely (almost) and make random access _very_ slow if
kept in a list (at least with 7.4 which is our inhouse version).
/Flemming
Yes. Keywords to learn about: "Mutable" and "Immutable". Try DejaNews to
get documentation on the subject.
Today, variables (including arrays) are the sole mutable things in Tcl,
hence the ease you noticed to make updates :^). If you look at the
Feather extension, you'll find the Vector type, which is a mutable list.
If you pile up vectors the way you did with list, you'll get a mutable
tree. But the overall scheme really close to what you ended up doing
with arrays (today's arrays and Feather's vector are both examples of
containers, which is all you need, so they are interchangeable,
regardless of considerations like first-class or not, which I guess you
are not primarily interested in...).
> I wouldn't mind an answer to my original question regarding "lreplace" and a
> multi-leveled list though....
One could imagine some kind of "deep" lreplace, using for example
"paths" ({1 5 3 2}) instead of indices (1).
But this would still be very inefficient, because the immutability of
the base list type implies copies, copies, copies... Your instinctive
move towards mutability (arrays) was a good one !
-Alex