Version 1 of lshift -Adding Unique Items to Lists of Fixed Length

Updated 2006-04-17 13:42:43

WJG (17/April2006) It's often useful to keep lists of unique items but those lists need to be of fixed length. Adding a new item to the list, means that the oldest item has to be deleted: a 'recent documents' list for example. Here's a simple solution. Indeed, its so simple that the comments are longer than the code itself!

 #---------------
 # lshift.tcl
 #---------------

 proc lshift {l i} {
  # if the item already exists, just return the list back
  if {![lsearch $l $i]} {return $l}

  # make a copy of the list with the new item at the top
  set j [linsert $l 0 $i]

  # return a list equalling the length of the original list sent
  set end [expr [llength $l] -1]
  return [lrange $j 0 $end]
 }

 #---------------
 # the ubiquitous demo
 #---------------
 proc demo {} {
  # just for the linux users
  catch {console show}

  # create a list
  foreach a {apple pear bannana} {
    lappend fruit $a
  }

  # the list before changes
  puts $fruit

  # cherry will be added, bannana will go
  set fruit [lshift $fruit cherry] 
  puts $fruit

  # we already have cherry, no change 
  set fruit [lshift $fruit cherry] 
  puts $fruit

  }

  demo

MG Apr 17 2006 - Did you know you can use lrange $list 0 end-1 to trim the last element from the list, and avoid the expr? A couple of suggestions, too: it might be better if you could specify a maximum length instead (recent document/history lists won't always be fully populated, and the user may clear it). Also, if an item is already in the list, it could be better to bring it to the beginning, rather than do nothing.