在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
}
我想知道是否有更好的方法。
答案 0 :(得分:2)
此代码在您的代码和提到的lreplace
代码abendhurt之间进行计时。这样做的主要优点是它比两者都更紧凑和可读。
proc shift list_name {
upvar 1 $list_name listy
set listy [lassign $listy ret]
return $ret
}
答案 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
}