Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Append elements to nested list in TCL

Tags:

list

nested

tcl

I want to dynamically add elements to nested lists. Consider the following example:

set super_list {}
lappend super_list {00 01 02}
lappend super_list {10 11 12}
lappend super_list {20 21}

results in:

super_list = {00 01 02} {10 11 12} {20 21}
[lindex $super_list 0] = {00 01 02}
[lindex $super_list 1] = {10 11 12}
[lindex $super_list 2] = {20 21}

How do I append another value (e.g. 22) to [lindex $super_list 2]?

lappend [lindex $super_list 2] 22

does not work!

The only workaround I could think of so far is:

lset super_list 2 [concat [lindex $super_list 2] {22}]

Is this really the only way?

Thanks, Linus

like image 788
Linus Avatar asked Jul 30 '13 11:07

Linus


2 Answers

In Tcl 8.6 (the feature was added; it doesn't work in earlier versions) you can use lset to extend nested lists via the index end+1:

set super_list {{00 01 02} {10 11 12} {20 21}}
lset super_list 2 end+1 22
puts [lindex $super_list 2]
# ==>  20 21 22

You could address one past the end by using a numeric index too, but I think end+1 is more mnemonic.

like image 197
Donal Fellows Avatar answered Sep 28 '22 00:09

Donal Fellows


There's no direct method for lists to do this. You could at least wrap it up in a proc:

proc sub_lappend {listname idx args} {
    upvar 1 $listname l
    set subl [lindex $l $idx]
    lappend subl {*}$args
    lset l $idx $subl
}
sub_lappend super_list 2 22 23 24
{00 01 02} {10 11 12} {20 21 22 23 24}

An advatange of this approach is you can pass a list of indices to work in arbitrarily nested lists (like lset):

% sub_lappend super_list {0 0} 00a 00b 00c
{{00 00a 00b 00c} 01 02} {10 11 12} {20 21 22 23 24}
like image 40
glenn jackman Avatar answered Sep 27 '22 23:09

glenn jackman