compare lists


[ Zettels Traum ] [ search / suche ]

von dp am 14.Februar 97 um 20:42:28:

zu: Perlen aus dem Strom der Nachrichten im direct_L von Daniel am 22.Dezember 96 um 02:00:59:

Wolf wrote: (--edited on request, 20060310, dp)
>
> I got stuck and cannot think anymore. I have got three lists, and need to
> compare them to find only the entries that they have in common, i.e.:
>
> a = [1,2,3]
> b = [2,3,4]
> c = [3,4,5]
>
> Result must be 3 as this is the only common value.
>

Wolf,
Don't know if this would be less complicated than the one you have, but you
can compare any number of lists using this handler and it will return to
you a list of common numbers:

on findCommonNumbers listOfLists
  -- get the first list in the listOfLists and use it as test base
  set baseList = getAt(listOfLists, 1)
 -- this is to avoid messing up the original listOfLists
  set tempList = duplicate(listOfLists)
  set answerList = []
  repeat with aItem in baseList
    set findOne = TRUE
    repeat with aList in tempList
      if not(getOne(aList, aItem)) then
        set findOne = FALSE
        exit repeat
      end if
    end repeat
  -- will not include duplicated common numbers
    if (findOne = TRUE) and not(getOne(answerList, aItem)) then
      append answerList, aItem
    end if
  end repeat
  return answerList
end
In the message window:
put findCommonNumbers([[1,2,3],[2,3,4],[3,4,5]])
-- [3]
put findCommonNumbers([[1,3,3],[2,3,4],[3,4,5]])
-- [3]
put findCommonNumbers([[1,4,3],[2,3,4],[3,4,5]])
-- [4, 3]
put findCommonNumbers([[1,2,3,5],[2,3,4,5],[3,4,5],[2,4,5]])
-- [5]
put findCommonNumbers([[3,5],[2,3,4,5],[4],[2,4,5]])
-- []
Hope this help.
Nancy Cheng

This handler works.  You can pass it a list of any number of linear
lists and it will return one linear list that contains the
values common to all of the lists you pass it.  With your example,
you can do this in the message window:
put getCommonValues([[1,2,3],[2,3,4],[3,4,5]])
-- [3]
-------------------------------
on getCommonValues myLists
  -- myLists is a linear list of any number of linear lists
  -- this function returns a list that contains the values common
  -- to all of the input lists.  Should add type checking.
  set tNumOfLists = count(myLists)
  set tFirstList  = getAt(myLists, 1)
  set tReturnList = []
  repeat with tTestValue in tFirstList
    set tFoundFlag = FALSE
    repeat with tIndex = 2 to tNumOfLists
      if getPos(getAt(myLists, tIndex), tTestValue) <> 0 then
        set tFoundFlag = TRUE
      else
        set tFoundFlag = FALSE
        exit repeat
      end if
    end repeat
    if getPos(tReturnList, tTestValue) = 0 AND tFoundFlag then
      add tReturnList, tTestValue
    end if
  end repeat
  return tReturnList
end getCommonValues
------------------------------------
Good Luck ... Doug

>
There have been two very similar solutions postet already by Nancy Cheng and 
Doug Smith, both working perfectly and very high-speed. 
Especially, if the list of lists contains a large number of items. 
With few very long lists, however, this handler seems to have an advantage.

on getCommon ListofLists
  set theList = duplicate(ListofLists )
  repeat while Count(theList) > 1
    set list1=getat(theList,1)
    set list2=getat(theList,2)
    deleteAt theList,1
    setAt theList,1,compare2Lists(list1,list2)
  end repeat
  return getat(theList,1)
end
on compare2Lists list1, list2
  set rslt=[]
  repeat with anItem in list1
    if getOne(List2, anItem) and not getOne(rslt,anItem) then append rslt,anItem
  end repeat
  return rslt
end

Daniel Plaenitz




Dazu:























D. Plänitz