Recursive Lists in Tcl


 
Thread Tools Search this Thread
Top Forums Shell Programming and Scripting Recursive Lists in Tcl
# 1  
Old 06-10-2011
Recursive Lists in Tcl

Hi,
I am new to tcl programming, i want to know how to write a procedure for list operations taking the user input from command line and outputs the the index of each element in the list.

Eg:
input list is : { 1 2 {ab cde} {acf t12 l34} 3 5{43 {try 5 }} } something like this.

output should help to get index as 20 for ab and 210 for element cde...etc
Is this an example for recursion??

Regards,
Leo
# 2  
Old 06-13-2011
Some thing like this will work as long as nested lists have more than one members.

Code:
set a {a b {c {d e}}}
proc list_eval {list_name {prefix {}}} {
set end_point [expr [llength $list_name] -1]
    for {set start_point 0} {$start_point <= $end_point} {incr start_point} {
        if {[llength [lindex $list_name $start_point]] == 1} {
            puts "Index for [lindex $list_name $start_point] is $prefix$start_point"
        } else {
            append prefix $start_point
            list_eval [lindex $list_name $start_point] $prefix
        }        
}    
}    
list_eval $a

Output will be :
Index for a is 0
Index for b is 1
Index for c is 20
Index for d is 210
Index for e is 211

---------- Post updated 06-13-11 at 09:47 AM ---------- Previous update was 06-12-11 at 04:11 PM ----------

My pvs posted code was not correct, it will not work if last members of a main list is not a part of nested list. You can use modified code.

Code:
set a {a b {c {d e} h} i}
set glob_var {}
proc list_eval {list_name {prefix {}}} {
    global glob_var
set end_point [expr [llength $list_name] -1]
    for {set start_point 0} {$start_point <= $end_point} {incr start_point} {
        if {[llength [lindex $list_name $start_point]] == 1} {
            puts "Index for [lindex $list_name $start_point] is $prefix$start_point"
           if {$start_point == $end_point} {
           set glob_var [string range $glob_var 0 end-1]
            }
        } else {
            append glob_var $start_point
            list_eval [lindex $list_name $start_point] $glob_var
       }        
}    
}    
list_eval $a

Output:
Index for a is 0
Index for b is 1
Index for c is 20
Index for d is 210
Index for e is 211
Index for h is 22
Index for i is 3
This User Gave Thanks to sarbjit For This Post:
# 3  
Old 06-14-2011
Hi,
Thanks for the help, it works fine.

---------- Post updated 06-14-11 at 01:12 PM ---------- Previous update was 06-13-11 at 03:38 PM ----------

Hi,

If to same input list i use linsert to insert a new element, how do i modify the present program such the the index update is also taken care of for newly added element and also rest of the elements.

Thanks,
Leo
# 4  
Old 06-14-2011
You need to execute the procedure again in order to calculate the index of newly created list.

For instance if my initial list list1 has elements as 'a b c' and i inserted an element at last i need to pass this modified list again to procedure.

Are you saying you want to handle lindex based on index returned by procedure? like for "h" it is 22, so if you add new element it should add in nested list.

Can you pls elaborate on your requirement.
# 5  
Old 06-14-2011
Let me put this way,
As in eg :
My original list: {a b {c {d e}}}
with indexes
a = 0
b = 1
c = 20
d = 210 etc

I ask user as :
puts "Enter new element"
gets stdin newel
puts "Enter index of new element"
gets stdin newind

So, if user gives newel as 1 and index as 2 my new list should be : { a b 2 {c {d e}}}
and correspondingly new indices should be
a = 0
b = 1
2 = 2
c = 30 etc...
and if user enters and index improper say in this eg user enters newind as 510 it should display error.

So how can take care of these in the earlier tcl script.

Thanks
# 6  
Old 06-15-2011
Hi,

I tried the code as this:

Code:
set a "a cd {{{{lm st rm} {0 1} 2}} {1 0}} 5 6 7 8 {} ab"
set glob_var {}
proc list_eval {list_name {prefix {}}} {
    global glob_var
set end_point [expr [llength $list_name] -1]
    for {set start_point 0} {$start_point <= $end_point} {incr start_point} {
        if {[llength [lindex $list_name $start_point]] == 1} {
            puts "Index for [lindex $list_name $start_point] is $prefix$start_point"
           if {$start_point == $end_point} {
           set glob_var [string range $glob_var 0 end-1]
            }
        } else {
            append glob_var $start_point
            list_eval [lindex $list_name $start_point] $glob_var
       }        
}    
}    
list_eval $a

In output i see
Code:
Index for {{lm st rm} {0 1} 2}  is 20.

How can i fix this ???

Thanks,
Leo

Last edited by Franklin52; 06-15-2011 at 09:56 AM.. Reason: Please use code tags
# 7  
Old 06-15-2011
I did something like this to achieve this, you can refine this code further. Basic just here is if length of list is 1, then you need to check whether this has further some members or not.

Code:
set a "a cd {{{{lm st rm} {0 1} 2}} {1 0}} 5 6 7 8 {} ab"
set glob_var {}
proc list_eval {list_name {prefix {}}} {
    global glob_var
set end_point [expr [llength $list_name] -1]
    for {set start_point 0} {$start_point <= $end_point} {incr start_point} {
        if {[llength [lindex $list_name $start_point]] && ![regexp ^\{ [lindex $list_name $start_point]]} {
            puts "Index for [lindex $list_name $start_point] is $prefix$start_point"
           if {$start_point == $end_point} {
           set glob_var [string range $glob_var 0 end-1]
            }
        } elseif {[llength [lindex $list_name $start_point]] && [regexp ^\{ [lindex $list_name $start_point]]} {
            set new_string1 [string trimleft [lindex $list_name $start_point] \{ ]
            set new_string2 [string trimright $new_string1 \}]   
            append glob_var $start_point
            list_eval $new_string2     
        } else {
            append glob_var $start_point
            list_eval [lindex $list_name $start_point] $glob_var
       }        
}    
}    
list_eval $a

Login or Register to Ask a Question

Previous Thread | Next Thread

10 More Discussions You Might Find Interesting

1. Shell Programming and Scripting

Combining lists

Hello everybody. My operating system is Fedora30, shell - bash I faced combining lists. I will be glad for help regarding strings, arrays and so on. The bottom line is as follows. It is necessary to combine each element from the first list with elements from the second. if the second is longer... (4 Replies)
Discussion started by: nezabudka
4 Replies

2. Shell Programming and Scripting

Issue with Lists

Hey guys, so I wrote this simple script. The first time I typed it all out, I had the issue where whatever choice I entered, it would simply tell me it was a "bad selection" aka the else output. I redid everything, and now no matter the choice, it does the backup option.. My brain hurts, and... (12 Replies)
Discussion started by: jakelawson44
12 Replies

3. UNIX for Dummies Questions & Answers

Lists in awk

Hi togehter! I would like to write an awk script which prints the first column divided by the sum of the second column: So if this is my list 1 2 2 1 3 1 4 1 it should print a list like this: 1/5 2/5 3/5 4/5 My idea was to use END like this: (3 Replies)
Discussion started by: bjoern456
3 Replies

4. Shell Programming and Scripting

Listing cross cases within lists in TCL

Hello everyone, I am new here forgive me if I omit something, I have a problem which I can't seem to solve using TCL so I am posting it here. Here it is : I retrieve a UNKNOWN number of lists from an XML file. Let's skip the part where I retrieve these lists and say for example that you have... (4 Replies)
Discussion started by: Noobard
4 Replies

5. Shell Programming and Scripting

get the lists

I expert, I may cross post something similar but I dirtyed my quesion somehow to be clear in the thread #cat file1 88dee gcc: Grok for callconvention-hard to enable hard float a2ad2 eglibc: package mtrace separately 61487 python: bump PR of packages after update of distutils.bbclass... (1 Reply)
Discussion started by: yanglei_fage
1 Replies

6. Shell Programming and Scripting

combining two lists

Hi, So I I received two lists for my merchandise and both are similar but differences do occur. I want to combine two lists that have similar names but I dont want the similar name to come up twice because I will end up purchasing two of those items. Heres an example below (file is massive). ... (1 Reply)
Discussion started by: kylle345
1 Replies

7. Shell Programming and Scripting

Using foreach with two lists

Hi everybody, I'm trying to use a foreach command with two lists. The file.txt looks like this: var1: 100 200 300 var2: 3 6 9 I'm trying to use a foreach command to associate the two variables together. My script looks like this: #! /bin/tcsh set a=(`cat file.txt | grep 'var1' | cut -d... (8 Replies)
Discussion started by: SimonWhite
8 Replies

8. Shell Programming and Scripting

Shell Script to Create non-duplicate lists from two lists

File_A contains Strings: a b c d File_B contains Strings: a c z Need to have script written in either sh or ksh. Derive resultant files (File_New_A and File_New_B) from lists File_A and File_B where string elements in File_New_A and File_New_B are listed below. Resultant... (7 Replies)
Discussion started by: mlv_99
7 Replies

9. Shell Programming and Scripting

How to get the files lists

Hi All, Need the help in getting the file list which are generated for the time period. example if i want to get the list of file generated between 11 to 12 clock. i used the find command search the files with -cmin flag with -60. find /home/test/* -cmin -60 -type f -exec ls {} \; ... (2 Replies)
Discussion started by: nmadhuhb
2 Replies

10. Programming

C++ programming using lists

To test this program it must create 2 integer lists - list1, list2 - and then read and process a series of list commands from a file named "data.txt". Each command and any associated values, list number, value appears on a separate line. All I can do is get it to input the integers and then... (3 Replies)
Discussion started by: tiger13e
3 Replies
Login or Register to Ask a Question