2015-07-15 3 views

ответ

0
set x {{A 0} {B 1} {C 2} {D 3} {6 {F G}}} 

set y {{{{1 2 {3 4}}}}} 

array set myarr {} 
set count 0 
proc printListElem {myList} { 
    global myarr count 
    for {set i 0} {$i <[llength $myList]} {incr i} { 
     set currentElem [lindex $myList $i] 
     if {![info exists myarr($count,${currentElem})]} { 
      incr count 
      set myarr($count,${currentElem}) 1 
      printListElem $currentElem 
     } else { 
      incr count -1 
      break 
     } 
    } 
} 

printListElem $y 
foreach idx [lsort [array names myarr]] { 
    lassign [split $idx ,] key value 
    puts "[string repeat "+" $key]$value" 
} 

Это один будет работать для всех уровней вложенности списков и выход будет показано что-то подобное,

+{{1 2 {3 4}}} 
++{1 2 {3 4}} 
+++1 2 {3 4} 
++++1 
++++2 
++++3 4 
+++++3 
+++++4 

Количества + настоящее здесь будет представлять собой вложенный уровень элементов списка. (Спасибо г-ну Гленну за идею). Это может быть неэффективным, но это можно сделать и таким образом.

0

Если мы знаем глубину списка, мы можем только гнездятся некоторые foreach звонков:

foreach a $x { 
    foreach b $a { 
     puts "--> $b" 
    } 
} 

Но общее «перебрать все возможные вложенные списки» не существует в Tcl, так как концепция несовместима с Модель типа Tcl. Вы буквально не должны думать о ценностях таким образом, чтобы это вызывало разумный вопрос. Вы не строите произвольно деревья: вы строите конкретных деревьев, где уровни имеют смысл для проблемы.

(Основная проблема в том, что red hot cat одновременно список 3 пункта и строка 11 символов.)

2

Это довольно легко расширить ответ DINESH, чтобы сделать его по-настоящему рекурсивным:

set x {{A 0} {B 1} {C 2} {D 3} {4 {F G}}}; # Have added one more element 

proc printListElem {myList {level 1}} { 
    foreach elem $myList { 
     puts "[string repeat "+" $level] $elem" 
     if {[llength $elem] > 1} { 
      printListElem $elem [expr {$level + 1}] 
     } 
    } 
} 

printListElem $ х

+ A 0 
++ A 
++ 0 
+ B 1 
++ B 
++ 1 
+ C 2 
++ C 
++ 2 
+ D 3 
++ D 
++ 3 
+ 4 {F G} 
++ 4 
++ F G 
+++ F 
+++ G 
+0

@ Dinesh, вы хотите принять это в своем ответе? –

+0

Ничего себе !!! Это выглядит здорово. Лучше быть автономным вики-ответом. :). Фактически, я думал о том, чтобы сделать его более надежным, поддерживая большее количество вложенных уровней в списке. Позвольте мне обновить его в своем ответе. Надеюсь, что это будет эффективно. – Dinesh

0

Я вижу людей, которые пытаются повторять рекурсивно и прийти и я уверен, что некоторые из них могут не согласиться с этим, но ответ на вопрос «Как перебрать и распечатать все элементы в этого вложенного списка?» довольно просто.

Список содержит 4 элемента "1", "В 2", "C 3", "D 4", так что ответ был бы:

% set x {{A 0} {B 1} {C 2} {D 3}} 
{A 0} {B 1} {C 2} {D 3} 

% foreach item $x { 
    puts $item 
} 
A 0 
B 1 
C 2 
D 3 

Предположив, что один хотел бы сделать что-то с отдельными значениями затем их можно разделить с помощью lindex или lassign, например

% foreach item $x { 
    lassign $item char num 
    puts "char = $char, num = $num" 
} 
char = A, num = 0 
char = B, num = 1 
char = C, num = 2 
char = D, num = 3 

foreach также может принимать несколько значений, поэтому также будет возможно сделать это таким образом:

foreach item $x { 
    foreach {char num} $item { 
     puts "char = $char, num = $num" 
    } 
} 

На практике не будет иметь случайных уровней вложенных списков для хранения полезных данных, но если у кого-то действительно есть такие данные, возможно, стоит посмотреть на dict.

В качестве примера:

% set x {A {B 2} C {D {E 5}} F 6} 
A {B 2} C {D {E 5}} F 6 
% dict get $x A 
B 2 
% dict get $x A B 
2 
% dict get $x C D E 
5 
% dict get $x F 
6 
Смежные вопросы