2016-10-24 2 views
0

У меня есть список, содержащий список.Добавить суффикс для списка TCL

{ 
    {1, A}, 
    {2, A}, 
    {4, A}, 
    {6, B}, 
    {2, B}, 
    {7, C} 
} 

Как выполнить поиск второго элемента и добавить индекс, если его дублировать?

Ожидаемый результат:

{ 
    {1, A<0>}, 
    {2, A<1>}, 
    {4, A<2>}, 
    {6, B<0>}, 
    {2, B<1>}, 
    {7, C} 
} 
список
+0

Это не правильный список Tcl. –

+0

Вы хотите только добавить '<0>', если есть более одной записи с этим именем? Являются ли элементы гарантированными смежными? –

ответ

1

Использование Tcl 8.6

proc update {list} { 
    lmap elem $list { 
     set val [lindex $elem end] 
     set n [expr {[incr count($val)] - 1}] 
     lset elem end "$val<$n>" 
    } 
} 

set a {{1 A} {2 A} {4 A} {6 B} {2 B} {7 C}} 
set new [update $a] 
1

Tcl обычно не имеет сепараторы, кроме пробелов между элементами, и где есть подсписок, который представлен элементы в фигурных скобках запятая явно запрещена после подсписка ,

set list { 
    {1 A} 
    {2 A} 
    {4 A} 
    {6 B} 
    {2 B} 
    {7 C} 
} 

set res {} 
foreach item $list { 
    set letter [lindex $item 1] 
    if {[info exists num($letter)]} { 
     incr num($letter) 
    } else { 
     set num($letter) 0 
    } 
    lset item 1 $letter<$num($letter)> 
    lappend res $item 
} 

Алгоритм состоит из обхода списка списков с foreach и глядя на письмо, которое является второй элемент (индекс # 1) в подсписке. Массив, num используется для подсчета количества раз, когда каждая буква имела место. Если существует num($letter), мы уже считали это письмо и просто увеличиваем счет. Если это не так, это новая буква, и мы подсчитаем, что число равно 0. Мы пишем (используя lset) письмо вместе с суффиксом, содержащим счетчик, и, наконец, добавляем измененный подписчик в список res.

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

set res {} 
lmap item $list { 
    set letter [lindex $item 1] 
    if {[info exists num($letter)]} { 
     incr num($letter) 
    } else { 
     set num($letter) 0 
    } 
    lset item 1 $letter<$num($letter)> 
} 

Документация: foreach, if, incr, info, lappend, lindex, lmap (for Tcl 8.5), lmap , lset, set

Смежные вопросы