2011-10-10 46 views
5

Tclのリストからサブリストを削除します。私はlreplaceを使用してメインリストのためにそれを行う方法を知っていますが、私はサブリストのためにそれを行う方法を知らない。たとえば :tclのリストからサブリストを削除します。

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

は今、私は内部リスト{ {3 4} {4} }から{4}を削除したいです。 最終的なリストは以下のようになります。

a { 1 2 { {3 4} } }

彼に点在する方法を提案してください。

+1

私たちが欠けているのは、削除する要素を選択するために必要な基準です。つまり、常に3番目のサブリストの2番目のサブサブリストなのでしょうか? –

+0

また、lreplaceは実際には新しいリストを作成しません。代わりに実行しません –

+0

リスト{{3 4} {4}}の内部サブリストに2つ未満の要素がある場合は、それを削除してください。 {3 4}のように要素がありますが、{4}には要素が1つしかないので、{4}を削除する必要があります。 – Ruchi

答えて

2

内部サブリストを取得するには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

関連する問題