ldiff

Find the difference of two lists, i.e. the list of elements that occur in list a but not in list b (and not the inverse of the intersection, i.e. the list of elements that occur in either one of the two lists but not in the other).

package require Tcl 8.5
proc ldiff {a b} {
    lmap elem $a { expr {$elem in $b ? [continue] : $elem} }
}

ldiff {2 3 4 5 6 7 8 9 10} {2 3 5 7}
# -> 4 6 8 9 10
ldiff {1 2 3} {2 3 4}
# -> 1

This implementation probably isn't very efficient, but there you go.

Guys? No one else seems to care about this operation. It's not mentioned anywhere else on the wiki (yet, I'm going to add it to a couple of pages where I think it fits); it's not one of the listx functions. Don't you ever need to remove one set of elements from another? I use this command all the time!


Gotta move with the times, it's not 2007 anymore!

The "new" in operator is more expressive than lsearch -exact, and, as I found today (2014-01-21), quite a bit faster. So my old implementation gets retired (but I'll leave it here a while for pre-8.5 Tclers).

proc ldiff {a b} {
    lmap elem $a {
        expr {[lsearch -exact $b $elem] > -1 ? [continue] : $elem}
    }
}

gkubu - 2013-12-31 17:15:58

see also struct::set, http://tcllib.sourceforge.net/doc/struct_set.html (subcommand difference)