I have two lists
I am trying to do remove_from_list $a1 $b1 >> {a c d}
Is there a function that can operate on lists on tcl?
To begin with, you can't use brackets for list literals. Brackets are used for command substitution in Tcl.
Instead, use the list-making command, list
% set a1 [list a b c d e f]
a b c d e f
Or, more or less equivalently:
% set b1 {b f e}
b f e
There is no standard command to subtract one list from another. It's very easy to construct a filter, though.
You can filter out items in a1 that are in b1 by an lmap (list map) filter:
lmap item $a1 {
if {$item ni $b1} {
set item
} else {
continue
}
}
# results in
a c d
The if command inside the lmap body determines if an item is not in (ni)$b1. If this is true, the value of the item becomes a part of the result. If it is false, the item is skipped.
In Tcl 8.5 and earlier, there is no lmap. In that case, one can copy-and-paste an ersatz lmap (works the same) into the code: link below.
Or, one can use foreach instead. It's a little messier but works.
set res {}
foreach item $a1 {
if {$item ni $b1} {
lappend res $item
}
}
% set res
a c d
Documentation: continue, foreach, if, lappend, list, lmap (for Tcl 8.5), lmap, ni (operator), set
You can also use an array. It's easy to add and remove elements
% foreach elem $a1 {set x($elem) 1}
% foreach elem $b1 {unset x($elem)}
% set result [array names x]
d a c
It's a pretty efficient approach too, only a single pass through each list.
Or use a dictionary to maintain the original insertion order:
% foreach elem $a1 {dict set y $elem 1}
% foreach elem $b1 {dict unset y $elem}
% set result [dict keys $y]
a c d
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With