linsert inserts
elements into a
list.
Synopsis edit
-
- linsert list index element1 ?element2 element3 ...?
This returns a list that consists of
list with the given
elements inserted at
index. It does not modify
list itself.
Description edit
linsert returns a new list, leaving the original list unmodified. To "modify" a list:
set list [linsert $list 0 myvalue]
or, if the list is large make sure the list is unshared for
linsert so that the internal
Tcl_Obj can be re-used for the return value:
set list [linsert $list[set list {}] 0 myvalue]
The following proc makes it a little easier:
proc lipinsert {_list index args} {
upvar $_list list
set list [linsert [K $list [set list ""]] $index {*}$args]
}
> set A [list 1 2 3]
1 2 3
> lipinsert A 1 a b c
1 a b c 2 3
DKF 2004-10-26:
linsert can be used to create a
lprepend command that is like
lappend except that it puts the values at the start of the list:
proc lprepend {var args} {
upvar 1 $var v
lappend v ;# Used as a an "is a list" check and to do var creation
set v [linsert $v[set v {}] 0 {*}$args]
}
Lars H: Has the above any advantage in comparison with
set v [linsert $v [set v 0] {*}$args]
which is anyway slightly shorter? (OK, it can be used also where there isn't another argument to place the
set v <whatever> in, but what about those cases where an alternative exists? Is the idea of the example to establish a new idiom?)
PYK 2014-02-09:
Lars H was spot-on back in 2004. A new idiom has indeed been established.
linsert can be used to append elements to a list. In contrast with
lappend, the list must already exist.
Unshared pure list edit
AMG:
linsert always returns an unshared pure list. This fact may be helpful for performance measuring, as I recently showed on the
Additional list functions page. Just give your list-to-be as the first argument, any valid index (e.g. 0) as the second, and no further arguments.
(I'm not sure if it's always, always pure, i.e. lacking in string representation, but it was when I tested it earlier today.)
Documentation Bug: end-relative index edit
This documentation bug, reported by
amg,
was fixed in 2010.
AMG: According to the man page, "
linsert produces a new list from
list by inserting all of the
element arguments just before the
index’th element of
list." When doing
end-relative indexing, this definition doesn't match the actual behavior. To explain how
index is interpreted, the
linsert man page refers to the
string index man page, which says that
end indicates the last element. From this I expect that
linsert {0 1 2} end x will return
0 1 x 2, the result of inserting
x just before the
end element of the list, which is
2. However, it actually returns
{0 1 2 x}, so when doing
end-relative indexing it inserts the new elements
just after the indicated index. An alternative, more plausible explanation is that it inserts the new elements such that the first or last of the inserted elements will occupy the indicated index.
Please see my related comments on the
lreplace page.
See also edit
- list
- contains links to all the other list commands