aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSteve Bennett <steveb@workware.net.au>2017-06-02 12:10:27 +1000
committerSteve Bennett <steveb@workware.net.au>2017-08-03 09:07:24 +1000
commit59f01cb74b4b6f8c32cc4083735050b233ad4380 (patch)
treea437d4ae73208503a45fe5cfc9c9d660dece6b94
parent00c8f8991c6dd72baa3a281db0631a8268086f2a (diff)
downloadjimtcl-59f01cb74b4b6f8c32cc4083735050b233ad4380.zip
jimtcl-59f01cb74b4b6f8c32cc4083735050b233ad4380.tar.gz
jimtcl-59f01cb74b4b6f8c32cc4083735050b233ad4380.tar.bz2
tree: Allow nodes to be deleted
Signed-off-by: Steve Bennett <steveb@workware.net.au>
-rw-r--r--tests/tree.test15
-rw-r--r--tree.tcl24
2 files changed, 39 insertions, 0 deletions
diff --git a/tests/tree.test b/tests/tree.test
index 5a7cf74..22a16f5 100644
--- a/tests/tree.test
+++ b/tests/tree.test
@@ -110,6 +110,21 @@ test tree-2.3 "walk bfs" {
set result
} {rootnode childnode1 root.c2 root.c3 childnode2 n.c4 n.c5 n.c5.c6}
+test tree-3.1 "delete nodes" {
+ $pt delete node6
+ set result {}
+ $pt walk root bfs {action n} {
+ if {$action == "enter"} {
+ lappend result [$pt get $n name]
+ }
+ }
+ set result
+} {rootnode childnode1 root.c2 root.c3 childnode2 n.c4}
+
+test tree-3.2 "can't delete root node" -body {
+ $pt delete root
+} -returnCodes error -result {can't delete root node}
+
$pt destroy
testreport
diff --git a/tree.tcl b/tree.tcl
index d897c51..38a0a94 100644
--- a/tree.tcl
+++ b/tree.tcl
@@ -60,6 +60,10 @@ package require oo
# THe default index is "end"
# Returns the name of the newly added node
#
+# $pt delete <nodename>
+#
+# Delete the given node and all it's children.
+#
# $pt walk <nodename> dfs|bfs {actionvar nodevar} <code>
#
# Walks the tree starting from the given node, either breadth first (bfs)
@@ -155,6 +159,26 @@ tree method insert {node {index end}} {
return $childname
}
+tree method delete {node} {
+ if {$node eq "root"} {
+ return -code error "can't delete root node"
+ }
+ $self walk $node dfs {action subnode} {
+ if {$action eq "exit"} {
+ # Remove the node
+ dict unset tree $subnode
+ # And remove as a child of our parent
+ set parent [$self parent $subnode]
+ if {$parent ne ""} {
+ set siblings [dict get $children $parent]
+ set i [lsearch $siblings $subnode]
+ dict set children $parent [lreplace $siblings $i $i]
+ }
+ }
+ }
+}
+
+
tree method lappend {node key args} {
if {[dict exists $tree $node $key]} {
set result [dict get $tree $node $key]