是否有一个Tcl相当于Perl的转变?

时间:2016-11-21 09:44:19

标签: list perl tcl time-complexity

在Perl / Ruby中,可以移动一个数组(类似于Tcl的列表),因此删除数组中的第一个项目并返回它。它的运行时间几乎不变。即,2个元素和200万个元素相同。 有没有类似于Tcl的东西?在某种程度上,它与Tcl的lappend项目相反。我们不是从顶部添加1,而是从底部删除一些东西。 代码应如下所示:

set k [ list 1 2 3 ]
puts [ shift k ]
> 1
puts [join $k ","]
> 2,3

我当然可以在proc中执行此操作:

proc shift {list_name} {
   upvar $list_name listy
   set ret [lindex $listy 0]
   set listy [lrange $listy 1 end ]
   return $ret
}

我想知道是否有更好的方法。

4 个答案:

答案 0 :(得分:2)

此代码在您的代码和提到的lreplace代码abendhurt之间进行计时。这样做的主要优点是它比两者都更紧凑和可读。

proc shift list_name {
    upvar 1 $list_name listy
    set listy [lassign $listy ret]
    return $ret
}

文档: lassignprocreturnsetupvar

答案 1 :(得分:2)

尝试lassign

set k {1 2 3 4}
set k [lassign $k i]
puts $i; # 1
puts $k; # 2 3 4

为了获得更好的性能,您可以在操作时取消设置列表:

set k [lassign $k[unset k] i]

使用一些upvar魔法,你可以编写自己的转变:

proc shift {list} {
    upvar 1 $list l
    set l [lassign $l result]
    return $result
}
# Usage:
set myList {1 2 3 4}
puts [shift myList]; # 1
puts $myList; # 2 3 4

答案 2 :(得分:2)

使用struct::list

package require struct::list
set li {1 2 3 4}
::struct::list shift li; # li is now {2 3 4}

答案 3 :(得分:1)

(如我的评论所述)

tclers维基中有一个page about lshift。根据{{​​3}}页面,与您的版本相比,lreplace的使用表现更好。

proc lshift listVar {
    upvar 1 $listVar l
    set r [lindex $l 0]
    set l [lreplace $l [set l 0] 0]
    return $r
}