2011-10-10 112 views
5

我想从Tcl列表中删除子列表。我知道如何使用lreplace做主列表,但我不知道如何为子列表执行此操作。 例如:从tcl列表中删除子列表

set a { 1 2 { {3 4} { 4 } } } 

现在我想从内部列表中删除{ {3 4} {4} }{4}。 最终名单应该是:

a { 1 2 { {3 4} } }

请建议如何点他的。

+1

我们缺少的是你需要选择要移除的元素的标准,即它总是第三个子列表中的第二个子子列表或其他东西? –

+0

也不是实际创建一个新列表,它不做替换 –

+0

条件是如果列表{{3 4} {4}}的内部子列表中少于两个元素,则将其删除。就像在{3 4}中一样,我们有元素,但在{4}中只有一个元素,所以我需要删除{4}。 – Ruchi

回答

2

合并lindex得到内部子列表lreplace删除提取的内部子列表的一个元素和lset以将修改的子列表放回原位。

但是老实说,我对你的数据模型感觉有些问题。

1
proc retlist {a} { 
    set nl "" 
    foreach i $a { 
     if {[llength $i] > 1} { 
      set nl2 "" 
      foreach i2 $i { 
       if {[llength $i2] > 1} { lappend nl2 $i2 } 
      } 
      lappend nl $nl2 
     } else { 
      lappend nl $i 
     } 
    } 
    return $nl 
} 

如果你需要变化的深度,你会失去这个代码。你需要递归。

% set a {1 2 {{3 4} {5}}} 
1 2 {{3 4} {5}} 
% retlist $a 
1 2 {{3 4}} 

由于外部列表永远不会显示在tclsh中。

1

它需要一些技巧来很好地完成:

proc lremove {theList args} { 
    # Special case for no arguments 
    if {[llength $args] == 0} { 
     return {} 
    } 
    # General case 
    set path [lrange $args 0 end-1] 
    set idx [lindex $args end] 
    lset theList $path [lreplace [lindex $theList $path] $idx $idx] 
} 

set a [lremove $a 2 1] 

这工作,因为这两个lsetlindex可以采取的路径,和他们做明智的事情有一个空的路径了。

+0

我想他的问题是要知道路径...因此他需要循环他的列表以查看他的列表/子列表中的哪个元素是单个值(他的标准)。 – unNamed