zerodb
zerodb

Reputation: 61

How to remove a list from list in tcl

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?

Upvotes: 3

Views: 9842

Answers (3)

greg
greg

Reputation: 46

# with struct::set from tcllib

package require struct::set  
set a1 {a b c d e f}  
set b1 {b f e}  
struct::set difference $a1 $b1 

# result in  
d a c  

Dokumentation: struct::set

Upvotes: 2

glenn jackman
glenn jackman

Reputation: 246807

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

Upvotes: 3

Peter Lewerin
Peter Lewerin

Reputation: 13252

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

Upvotes: 3

Related Questions