From Tcl 8.5 [L1 ], expr operator for list inclusion test.

Opposite of ni.


official reference
 if {$el in $list} ...

is equivalent to, but much nicer than

 if {[lsearch -exact $list $el] >= 0} ...

The negation ("not in") is ni. So 8.5 Tcl really makes us knights who say 'ni'... For users of earlier versions, the following little helper comes in handy:

 proc in {list el} {expr [lsearch -exact $list $el] >= 0}}
 if [in $list $el] ...

- rs 2007-04-26

Let's see - so it would be something like:

 set el Mon
 if {$el in {Mon Tue Wed Thu Fri Sat Sun}} {
   puts "Valid day abbreviation"
 } else {
   puts "Invalid day abbreviation"

Lordmundi 2011-03022

How come these aren't equivalent?

% set item foo
% set list "1 2 3 4 5 foo"
1 2 3 4 5 foo
% if { $item in $list } { puts "Yep" }                                    
% expr ($item in $list)
invalid bareword "foo"
in expression "(foo in 1 2 3 4 5 foo)";

it seems when using expr, you have to do some funky explicit casting:

% expr ("$item" in [list $list])

why is that?

AMG: It's because you're using parentheses instead of braces in your calls to expr. Parentheses have no special meaning to the Tcl interpreter, hence expr receives three arguments:

  1. (foo
  2. in
  3. 1 2 3 4 5 foo)

expr then concatenates these arguments to give the expression "(foo in 1 2 3 4 5 foo)", and it chokes on the fact that the first term is an invalid bareword.

In this case, your problem has nothing to do with the "in" operator.

Replaces your parentheses with braces, and expr will receive only one argument:

  1. $item in $list

expr itself will perform the variable substitutions, which is the way it should be. See also: Brace your expr-essions.

Lordmundi: Ahh. I see. So it should be:

% expr {$item in $list}
% set item "fsdfsdfsdf"
% expr {$item in $list}