Sort

From Director Online Wiki
Jump to: navigation, search

Description

global method and list function.

sorts a list.


Example

vList = [30,20,10]
sort(vList)

-- OR

vList.sort()

put vList
-- [10, 20, 30]


Sort order

Director's sort order depends on...

  • the platform
  • the data type
  • the value of the item

... but not necessarily in that order.

If you are sorting items of different ilks, be prepared for surprises. Sorting a list and then adding items may not give the same results as adding items and then sorting. Try this test:

aList = []
aList.sort()
aList.add(numToChar(255)&" = numToChar(255)")
aList.add(1e999)
aList.add("a")
aList.add("9")
aList.add(the maxInteger)
aList.add(sqrt(-1))
aList.add("A")
aList.add(10)
aList.add(9.0)
aList.add("10")
aList.add(9)
aList.add(1)
aList.add(1.0)
aList.add("1")
aList.add(numToChar(1)&" = numToChar(1)")
aList.add("")
aList.add([])
aList.add(VOID)
put aList
-- [<Void>, [], "", "� = numToChar(1)", "1", 1.0000, 1, 9.0000, "10", 10,
   2147483647, 9, "9", "A", "a", NAN, INF, "?ã‚Ä° = numToChar(255)"]
aList.append(VOID) -- unsorts the list
aList.sort()
aList.deleteOne(VOID) -- removes the extra VOID
put aList
-- [<Void>, [], "", "� = numToChar(1)", "1", 1, 1.0000, "10", 9, 9.0000,
    10, "9",  "A", "a", NAN, 2147483647, INF, "?ã‚Ä° = numToChar(255)"]

Strings

Director sorts alpha-numeric strings in alphabetical order. Uppercase letters are placed before their lowercase equivalents:

aList = ["ab", "aB", "Ab", "AB"]
sort aList
put aList
-- ["AB", "Ab", "aB", "ab"]

To be precise: strings are sorted in numToChar() order. For numbers between 128 and 255, numToChar() does not give the same character on Macintosh and Windows, Strings that use non-ASCII characters may be sorted in a different order on different platforms:

All number strings beginning with a low digit will be placed before all number strings beginning with a high digit:

aList = ["1", "9", "10"]
sort aList
put aList
-- ["1", "10", "9"]

If you need to sort number strings, pad the strings with preceding zeros in order to make the sort work correctly:

aList = ["01", "09", "10"]
sort aList
put aList
-- ["01", "09", "10"]

Numbers

Director sorts numbers in ascending order, unless the numbers are typed as strings. Floating point numbers may be placed before or after the equivalent integer string. From the test above:

["1", 1, 1.0000, 9, 9.0000, "9"]
["1", 1.0000, 1, 9.0000, 9, "9"]

Do not count on number strings being sorted correctly with pure numbers.

Testing whether a list is sorted

Unfortunately Director does not give us a built-in function to check if a list is sorted or not.

Using Lingo

The following method performs a comprehensive test. It works on both empty lists and lists where all the items or properties are all VOID.

on sortedP(aList) ---------------------------------------------------
  -- INPUT: <aList> should be a property list or a linear list
  -- OUTPUT: Returns TRUE if the list is sorted, FALSE if not, or an
  --         error symbol
  -------------------------------------------------------------------  
 
  if not listP(aList) then
    return #listExpected
  end if
 
  vCount = aList.count()
 
  if vCount then
    -- There is at least one element.  VOID will always be placed
    -- first in a sorted list
   
    case (ilk(aList)) of
      #list :
        if voidP(aList.getLast()) then
          -- The list may contain only VOID, and still be unsorted
          vSorted = voidP(min(aList))
         
          if vSorted then
            -- The list contains nothing but VOID.  Add two elements
            -- in reverse order, then check if they are placed
            -- in the right order
            aList.add(1)
            aList.add(0)
           
            vSorted = aList.getLast()
            aList.deleteAt(vCount + 1)
            aList.deleteAt(vCount + 1)
          end if
         
        else
          -- The last element is not VOID; add VOID and check if it
          -- appears at the end
          aList.add(VOID)
          vSorted = (aList.getLast() <> VOID)
         
          if vSorted then
            aList.deleteAt(1)
          else
            aList.deleteAt(vCount + 1)
          end if
        end if
       
      #propList :
        if voidP(aList.getPropAt(vCount)) then
          -- findPosNear acts differently if the list is sorted
          vSorted = (aList.findPosNear([]) <> vCount + 1)
         
         if not vSorted then
            -- All the properties may be VOID.  Add two elements in
            -- reverse order, then check if they are placed in the
            -- right order
            aList.addProp(1, 1)
            aList.addProp(0, 0)
           
            vSorted = (aList.getPropAt(vCount + 2) = 1)
            aList.deleteAt(vCount + 1)
            aList.deleteAt(vCount + 1)
          end if
        else
          -- The last property is not VOID; add a VOID property and
          -- check if it appears at the end
          aList.addProp(VOID, VOID)
          vSorted = (aList.getPropAt(vCount + 1) <> VOID)
         
          if vSorted then
            aList.deleteAt(1)
          else
            aList.deleteAt(vCount + 1)
          end if
        end if
    end case
   
  else
    -- Add two items in reverse order and check if they are placed
    -- in the right order
    case ilk(aList) of
      #list:
        aList.add(1)
        aList.add(0)
       
      #propList:
        aList.addProp(1, 1)
        aList.addProp(0, 0)
    end case
   
    vSorted = aList.getLast()
    aList.deleteAll()
   
  end if
 
  return vSorted
end sortedP

Using the vList xtra

Alternatively, you can use the sortP() method of the vList xtra (requires a Basic licence).