Hey Caleb & James,

With your insights,  I was able to cut down 18 lines of somewhat
obscure code to 6 lines that I find very readable.  That's such and
improvement on the quality of the code.

Though I expect you guys are tired ot this thread, I included the new
and old code below, along with results that both of them produce.

Again,  thank you very much for your insights.

Best wishes,
Richard


# Accept a new list as a string; extract an array of contiguous upper-
case letters as stock symbols, ignoring any duplicates (Test data)
# Delete any symbol in the current list that occurs here
sNewList = %{TMxxx CSCO COL INTC BRCM FDX AA CAT BUR FSLR MSFT',
		      PNC HPQ CSCO AMAT ORCL FCX ABX PVTB XHB CSCO TM FDX}

#===============
# New technique
#===============
aRawNewList = sNewList.scan(/[A-Z]+/)
aNewList = Set.new(aRawNewList ).to_a.sort
nDeleted = 0
aNewList.each { |sym| hCurrentList.delete sym and nDeleted += 1  if
hCurrentList[sym] }
show_array( aNewList, 10, "New List (unique:%d, dups:%d, deleted:%s)"
%
  [aNewList.size, aRawNewList.size - aNewList.size, nDeleted] , true)

#============================
# Old technique; No longer used
#============================
aNewList = []
s = StringScanner.new sNewList
upper = /[A-Z]+/
non_upper= Regexp.new(  upper.source.sub( /\[/, '[^' )  )
nNewSyms = nCurrSymsDeleted = 0
while not s.eos?
  case
    when s.skip(upper)
      nNewSyms+=1
      aNewList << s.matched unless aNewList.include? s.matched
      ( hCurrentList.delete s.matched and  nCurrSymsDeleted += 1)  if
	  hCurrentList[s.matched]
     else
       s.skip(non_upper)
  end
end
show_array( aNewList.sort, 10, "New List (%d unique; %d dups; %d curr.
deleted)" %
  [aNewList.size, nNewSyms - aNewList.size, nCurrSymsDeleted] )

#=======
# Output
#=======
===== New List (unique:19, dups:4, deleted:3) =====
AA ABX AMAT BRCM BUR CAT COL CSCO FCX FDX
FSLR HPQ INTC MSFT ORCL PNC PVTB TM XHB
=====   =====