'''[http://www.tcl.tk/man/tcl/TclCmd/lindex.htm%|%lindex]''', a [Tcl Commands%|%built-in] Tcl command, retrieves an [element] from a `[list]` or a nested Commands%|%built-in] Tcl command, retrieves an item from a [list] or a nested ** See Also ** [list]: [Trees as nested lists]: [lappend]: [linsert]: [llength]: [lrange]: [lreplace]: [lsearch]: [lsort]: [lindex forward compatibility]: [identity function]: one use for `lindex` [http://www.tcl.tk/man/tcl/TclCmd/lindex.htm%|%official reference]: [TIP] [http://www.tcl.tk/cgi-bin/tct/tip/22.html%|%22]: Multiple Arguments to `lindex`: [TIP] [http://www.tcl.tk/cgi-bin/tct/tip/45.html%|%45]: Empty index lists for `lindex` and `[lset]`: : '''lindex''' ''list'' ?''index ...''? : '''lindex''' ''list index'' ?''index ...''? ** Description ** Returns the ''index'''th element from ''list'', where the first element in Returns the ''index'''th [element] from ''list'', where the first element in the number of elements in list, an empty string is returned. If there is no ''index'' argument, ''list'' is returned even if it is not a well-formed list. the number of elements in list, an empty string is returned. ''index'' can be any of the forms described for `[string]` indices. ''index'' can be any of the forms described for [[`[string]`] indices. Where multiple ''index'' arguments are given, they specify a path to an element Where multiple ''index'' arguments are given, they specify a path to an element in a nested list. ====== specify a path to a element in a nested list. Thus, these three are equivalent: specify a path to an item in a nested list. Thus, these three are equivalent: ====== lindex $nestedList 1 2 3 lindex $nestedList {1 2 3} lindex [lindex [lindex $nestedList 1] 2] 3 ====== Without any indices, or with an empty ''indexList'', the contents of the ''list'' argument are returned without further interpretation, meaning that in this case, ''list'' isn't even checked to make sure it is a properly formatted list. Therefore, any value at all is valid. This can be useful when a function that simply returns its argument is needed. ** Discussion ** ** Disussion ** [LES] 2005-08-15: What does `lindex` do that `[lrange]` doesn't? The announcement of the nested list functionality was documented here as follows: Also note that recent http://purl.org/tcl/tip/ TIPs 22 and 45 have been implemented and comitted to Tcl 8.4 source CVS tree. Here is a summary of the new functionality from [Kevin Kenny]: ======none Jeff Hobbs today committed to the CVS HEAD at Sourceforge the changes described in TIP's 22 (Multiple Index Arguments to lindex), 33 (Add 'lset' Command to Assign to List Elements), and 45 (Empty index lists for [[lindex] and [lset]) These changes augment the [[lindex] command so that it can extract elements from sublists, for example: [lindex {{a b c} {d e f} {g h i}} 1 1] => e They also implement an [[lset] command that may be used to change individual elements within lists and sublists. Taken together, these commands can be used to treat lists as if they were linear arrays. For instance, the following procedure might be used to reverse the order of elements in a list. proc reverse { list } { set i 0 set j [expr { [llength $list] - 1 }] while { $j > $i } { set temp [lindex $list $i] lset list $i [lindex $list $j] lset list $j $temp incr i incr j -1 } return $list } Updated documentation for the commands is available in the 'doc/' subdirectory in the source tree. The original proposals may be found at http://www.purl.org/tcl/tip/22.htm http://www.purl.org/tcl/tip/33.htm http://www.purl.org/tcl/tip/45.htm -- 73 de [ke9tv]/2, Kevin KENNY GE Corporate R&D, Niskayuna, New York, USA ====== [LES] 2005-08-15: What does [[`lindex`] do that [[`[lrange]`] doesn't? [pmaage] take less time [schlenk] direct access to elements in nested lists. [LES] Look, Ma! No lindex! ====== proc picknested {argList args} { proc picknested { argList args } { for {set _depth 0} {$_depth < [llength $args]} {incr _depth} { set argList {*}[lrange $argList $_range $_range] set argList {expand}[lrange $argList $_range $_range] return $argList } ====== Testing: ======none % picknested {{a b c} {d e {foo bar hey} f} {g h i}} 0 a b c % picknested {{a b c} {d e {foo bar hey} f} {g h i}} 0 1 b % picknested {{a b c} {d e {foo bar hey} f} {g h i}} 1 2 foo bar hey % picknested {{a b c} {d e {foo bar hey} f} {g h i}} 1 2 0 foo % picknested {{a b c} {d e {foo bar hey} f} {g h i}} 1 2 2 hey ====== [schlenk]: Should have said 'easy' access. You can do the same with [schlenk] Should have said 'easy' access. You can do the same with lrange, yes. You do not need all list commands, most can be replaced by a proc (think lsearch, lsort, lreplace, linsert, lindex). Its just a tradeoff how many list commands exist. (see [struct::list] for some more). Having more or fewer commands is mostly an optimization in time or space. [Lars H]: I'd go further and say `[lrange]` still doesn't give you access to [Lars H]: I'd go further and say [lrange] still doesn't give you access to the nested elements--it's really [{expand}] (and in the case of the indices shimmering) that you rely on to pick out elements of lists (undo whatever list-quoting were applied to them). But why bother with [lrange], when it's all much simpler with [foreach]? ====== proc picknested2 {L args} { foreach index $args { if {$index < 0} then {return {}} foreach L $L { if {[incr index -1] < 0} then {break} if {[incr index -1]<0} then {break} } } return $L } ====== Remove the first and last `[if]` if you don't worry about correct behaviour Remove the first and last [[`[if]`] if you don't worry about correct behaviour [AMG], perhaps echoing [Lars H]: `[lrange]` can't directly be used to obtain a single element from a list. The closest it comes is to return a ''list'' whose sole element is the one you're looking for. The difference is the same as that between a value and a single-element list containing that value. For many values, there is no script-visible difference (unless you're measuring performance, see [shimmering]). But you cannot rely on this in general. Here's an example: