2016-11-21 20 views
2

在Perl/Ruby中,可以移動一個數組(類似於Tcl的列表),因此移除數組中的第一個項目並返回它。它的運行時間幾乎不變。即,對於2個元素和200萬個元素也是如此。 有沒有類似於Tcl的東西?在某種程度上,它與Tcl的lappend項目相反。我們不是在頂部添加1,而是從底部移除某些東西。 的代碼應該是這樣的:有沒有一個Tcl相當於Perl的轉變?

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

我可以在一個進程做到這一點,當然是:

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

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

+1

有一個[頁碼大約LSHIFT(http://wiki.tcl.tk/8177)在tclers維基。根據[Tcl gems page](http://wiki.tcl.tk/918),與你的版本相比,使用'lreplace'的表現更好。 – b2vincent

+1

謝謝。這是我最需要的東西。 – user1134991

+0

查看元堆棧溢出後,因爲您發現這是您所需要的最接近的,並且儘管有其他高質量的答案,我將我的評論轉換爲答案。 – b2vincent

回答

1

(如我的評論說)有一個在tclers維基一個page about lshift。根據Tcl gems頁面的說法,與您的版本相比,使用lreplace的表現更好。

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

此代碼在你的代碼和lreplace代碼abendhurt之間提到的時鐘。這樣做的主要優點是它比兩者都更緊湊和更易讀。

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

文檔: lassignprocreturnsetupvar

1

嘗試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 
+1

偉大的思想思想相似嗎? :)這個答案並沒有增加很多我的。 –

+0

是的,沒錯。也許我可以添加某種未設定的魔法(不共享對象),但是很好。 –

2

使用struct::list

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