Есть ли в Tcl сокращение для получения последовательного массива чисел? - PullRequest
2 голосов
/ 03 августа 2011

Например, в Perl, чтобы получить последовательный массив чисел от 1 до 10, вы можете просто сделать:

@myArray = (1 .. 10);

Два периода служат сокращением для этих операций вместо создания цикла for или выписывания всего этого вручную. В других языках, которые я использовал, есть что-то похожее.

Существует ли подобное сокращение в Tcl?

Ответы [ 4 ]

5 голосов
/ 04 августа 2011

За исключением выражений (которые являются их собственным небольшим языком) Tcl не имеет операторов и всегда является строго префиксным языком. Это означает, что нет такого удобного сокращения для создания циклов. С другой стороны, нет ничего особенно особенного в стандартных командах Tcl (за исключением незначительных деталей эффективности, которые здесь не имеют значения), поэтому создание ваших собственных не составит труда:

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”

Вы можете подделывать инфиксные операторы, используя неизвестный обработчик (как в ответе GrAnd), но это действительно довольно медленно по сравнению с вышеупомянутым.

5 голосов
/ 03 августа 2011

Не совсем этот, но

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

Также ищите в этом ключевом слове "iota", чтобы увидеть, как это можно сделать, используя однострочник.

5 голосов
/ 03 августа 2011

Вы можете определить метод:

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

И использовать его как:

set myArray [fillArray 1 10]

Вы даже можете украсить вызов процедуры, чтобы он выглядел как в perl,Для этого просто переопределите unknown процедуру:

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]
}

После этого вы можете написать просто:

set myArray [1 .. 10]

:)

1 голос
/ 03 августа 2011

Нет, подобного сокращения не существует в tcl.

Если вы действительно хотите сокращение, вы можете создать свою собственную команду, которая выглядит почти так же.Например:

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]"
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...