I often need to loop through a list of items and need both the index position, and the item itself:
set names {John Paul George Ringo}
set i 0
foreach name $names {
puts "$i - $name"
incr i
}
Output:
0 - John 1 - Paul 2 - George 3 - Ringo
Since I frequently do this, I decided to implement my own loop and call it for_item_index
for lack of creativity. Here is my loop and a short code segment to test it:
proc for_index_item {index item iterable body } {
uplevel 1 set $index 0
foreach x $iterable {
uplevel 1 set $item $x
uplevel 1 $body
uplevel 1 incr $index
}
}
# Test it
set names {John Paul George Ringo}
for_index_item i name $names {
puts "$i - $name"
}
I have tested it with break
, and continue
and found my new loop performs as expected. My concern is the excessive use of uplevel
command in the code. I am seeking reviewers to give me tips for improving it.
Here are my own review of my code:
- Excessive use of
uplevel
- The index always starts at zero. There are times when I want it to start at 1 or some other values. To add that feature, I will probably introduce another parameter,
startValue
- Likewise, the index always get incremented by 1. The user might want to increment it by a different values such as 2, or -1 to count backward. Again, introducing another parameter,
step
might help, but at this point, the loop is getting complicated.
lassign $indexexpr idxvar start step; if {$start == ""} {set start 0}; if {$step == ""} {set step 1}
(shame about comment code formatting) \$\endgroup\$