Nate
Nate

Reputation: 33

Is there shorthand in Tcl to get a sequential array of numbers?

For example, in Perl, to get a sequential array of numbers from 1 to 10, you could simply do:

@myArray = (1 .. 10);

The two periods serve as shorthand for this operations instead of making a for loop or writing the whole thing out manually. Other languages I've used have something similar also.

Does a similar shorthand exist in Tcl?

Upvotes: 2

Views: 4795

Answers (4)

GrAnd
GrAnd

Reputation: 10221

You can define the method:

proc fillArray {a b} {
    eval return \[list $a [string repeat "\[incr a\] " [incr b -$a]]\]
}

And use it as:

set myArray [fillArray 1 10]

You even can beautify the call of procedure to make it look as in perl. For that just redefine unknown procedure:

rename unknown __unknown
proc unknown {args} {
  if {[llength $args] == 3} {
    lassign $args a op b
    if {[string is integer $a] && $op == ".." && [string is integer $b]} {
      return [fillArray $a $b]
    }
  }
  return [uplevel __unknown {*}$args]
}

After that you can write just simple as:

set myArray [1 .. 10]

:)

Upvotes: 7

Donal Fellows
Donal Fellows

Reputation: 137667

With the exception of expressions (which are their own little language) Tcl has no operators and is always a strictly prefix-driven language. This means that there isn't such a convenient shorthand for doing loops. On the other hand, there's nothing particularly special about Tcl's standard commands (apart from some minor efficiency details that don't matter here) so making your own is no problem:

proc .. {from to} {
    if {$from >= $to} {
        for {set i $from} {$i <= $to} {incr i}    {lappend out $i}
    } else {
        for {set i $from} {$i >= $to} {incr i -1} {lappend out $i}
    }
    return $out
}

puts [.. 1 10];   # --> “1 2 3 4 5 6 7 8 9 10”

You can fake infix operators by using an unknown handler (as in GrAnd's answer) but that's really quite slow by comparison with the above.

Upvotes: 5

Bryan Oakley
Bryan Oakley

Reputation: 386105

No, a similar shorthand does not exist in tcl.

If you really want shorthand, you can create your own command that looks almost the same. For example:

proc : {start ignore end} {
    set result []
    for {set i $start} {$i <= $end} {incr i} {
        lappend result $i
    }
    return $result
}

puts "from 1 to 10: [: 1 .. 10]"

Upvotes: 1

kostix
kostix

Reputation: 55503

Not quite this one, but

% package require struct::list
1.6.1
% struct::list iota 10
0 1 2 3 4 5 6 7 8 9

Also search this for the "iota" keyword to see how this can be done using a one-liner.

Upvotes: 5

Related Questions