Switch to ns_set and just ignore the value side of things.
ns_set update will add a key if it does not exist or replace a key if it does.
Presumably replacing with exactly what was there before is the same as
"append a value to a list, but only if the value isn't already on the list"
Or hack something new out of the ns_set update code.
On Friday 03 May 2002 07:44 pm, Andrew Piskorski wrote:
> I sometimes need to assemble a list of unique values, while preserving
> the order of the list. So when creating the list, I append a value to
> a list, but only if the value isn't already on the list. In Tcl,
> usually I do this with the bb_lappend_uniq procedure below. It uses a
> helper Tcl array to maintain the state info of what values are already
> on the list - presumably this is faster than calling lsearch every
> time.
>
> But does anyone have something to generate the same unique Tcl list,
> but implemented in C? Or something else similar?
>
> Reason I care, is I have lots of key/value pairs, and each key is made
> up several strings concatenated together. For discussion, we'll
> assume each key has the structure "ABCD". And what I need, is a list
> of all the unique SUB-keys "AB". Right now, I do that in Tcl. But
> that extra pass of grubbing through all my keys is dominating my
> execution time - and it's too slow. (There's regexp involved, etc.)
>
> But, I'm generating all those keys and sub-keys myself in my C code,
> so rather than tuning my Tcl, the obvious thing to do is to assemble
> my unique list of subkeys right there in C, and thus avoid having to
> iterate through all my data an extra time in Tcl.
>
> Note I still want to end up with a Tcl list of unique sub-keys, I just
> want the implementation done in C. It would be extra nice if I could
> pass in a Tcl array or NSV name from Tcl to maintain the state of
> what's already on the list, because then I could pre-populate it if I
> wanted to, in order to append to an already existing list, etc. But
> that's frosting really, it'd be ok if the C code always starts with an
> empty list and the state array/nav isn't accessible to anything
> outside my C function.
>
> Well, I've probably rambled on too long about something so simple, but
> before I start implementing my simple solution (using Tcl_AppendResult
> and a TclHashTable to maintain list state, I think), I figured I'd ask
> if anyone else has already done it...
>
> And of course, maybe somebody will point out some entirely different
> and better way to do this, instead. :)
>
>
> ad_proc bb_lappend_uniq {{
> -key_prefix {}
> } list_name item_name luniq_state_arr_name} {
>
> Appends an item to a list <em>only</em> if that item is not already
> on the list. In order to avoid doing an lsearch of the whole list
> for every single lappend, takes a helper state array which is
> <em>must</em> alrady have an array variable defined for each item
> already on the list, if the list is not empty.
>
> } {
> upvar 1 $list_name L
> upvar 1 $item_name item
> upvar 1 $luniq_state_arr_name arr
>
> if { [info exists arr("${key_prefix}${item}")] } {
> # Do nothing, this left_key is already on the list.
> } else {
> lappend L $item
> set arr("${key_prefix}${item}") 1
> }
> }
>
> ad_proc bb_luniq {L} {
> Returns a list with all duplicates removed, and keeping the
> original order.
> <p>
> Code taken from the
> <a href="http://mini.net/tcl/526.html">Tcl'ers Wiki</a>
> } {
> set t {}
> foreach i $L {if {[lsearch -exact $t $i]==-1} {lappend t $i}}
> return $t
> }