Version 30 of lindex

Updated 2014-08-19 20:36:44 by AMG

lindex , a 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
lindex forward compatibility
identity function
one use for lindex

Documentation

official reference
TIP 22 : Multiple Arguments to lindex
TIP 45 : Empty index lists for lindex and lset

Synopsis

lindex list ?index ...?
lindex list indexList

Description

Returns the indexth element from list, where the first element in Returns the indexth 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. If there is no index argument, list is returned even if it is not a well-formed list. 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

lindex {{a b c} {d e f} {g h i}} 1 1 ;# -> e
lindex {{a b c} {d e f} {g h i}} 1 1] ;# -> e

If one ''index''' is given, and it is a list of indexes, those indexes also
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?
[pmaage] take less time [schlenk] direct access to elements in nested lists.  
[pmaage] take less time [schlenk] direct access to elements in nested lists.  
[LES] Look, Ma! No lindex!

proc picknested {argList args} {

   for  {set _depth 0} {$_depth < [llength $args]} {incr _depth} {
       set _range [lrange $args $_depth $_depth]
       set argList {*}[lrange $argList $_range $_range]
   }
   return $argList

}

Testing:

% 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
`[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
the nested elements--it's really [{*}] (and in the case of the indices
the nested elements--it's really [{*}] (and in the case of the indices
shimmering) that you rely on to pick out elements of lists (undo whatever
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 {$index >= 0} then {return {}}
    }
    return $L

}

Remove the first and last `[if]` if you don't worry about correct behaviour
for out-of-bounds indices.

[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:
[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:

lindex {{hello world} {how are you}} 0 ;# hello world lindex {"hello world" "how are you"} 0 ;# hello world lrange {"hello world" "how are you"} 0 0 ;# {hello world}