This script combines some useful methods of AS3 Array with those of Lingo List. Moreover, some of the original Lingo list methods like add(), append(), deleteAt() and getAt() are modified. For example, getAt() method returns VOID instead of “index out of range” exception.
new( {…args} ) | - | Returns a new list, you can specify the initial values as arguments. |
dispose() | - | Destroys the list |
shuffle() | - | Shuffles the list values in-place, using Fisher–Yates algorithm. |
add( {…args} )* | - | Adds values to a list. For a sorted list, the values are placed in their proper order. |
getAt()* | - | Prevents “Index out of range” exception. |
deleteAt()* | - | deleteAt()* |
append( {…args} )* | - | Adds the specified values to the end of a list. |
shift() | - | Removes the first element from an array and returns that element. |
pop() | - | Removes the last element from a list and returns the value of that element. |
unshift( …args ) | - | Adds one or more elements to the beginning of a list and returns the new count of the list. |
slice( startIndex, endIndex ) | - | Returns a new list that consists of a range of elements from the original list, without modifying the original list. |
splice( startIndex, deleteCount{, … values} ) | - | Adds elements to and removes elements from a list. |
some( handler{, object} ) | - | Executes a test function on each item in the list until an item is reached that returns TRUE. |
every( handler{, object} ) | - | Executes a test handler on each item in the list until an item is reached that returns FALSE for the specified handler. |
filter( handler{, object} ) | - | Executes a test handler on each item in the list and constructs a new list for all items that return TRUE for the specified handler. |
forEach( handler{, object} ) | - | Executes a handler on each item in the list. |
map( handler{, object} ) | - | Executes a handler on each item in a list, and constructs a new list of items corresponding to the results of the handler on each item in the original list. |
sort( {symbolOrder} ) | - | Sorts the list in ascending or descending order.( #ASC / #DESC ) |
sortOn( intColumnIndex{, symbolOrder} ) | - | Sorts the list on given “column”. |
concat() | - | Concatenates the elements specified in the parameters with the elements in a list and creates a new list. |
reverse() | - | Reverses the list in-place. |
join( separator ) | - | Returns a string, constructed by items in the list, with the separator inserted between them. |
toString() | - | Returns a string that represents the elements in the specified list, separated by commas. |
lastIndexOf( searchElement, startIndex ) | - | Searches for an item in a list, working backward from the last item, and returns the index position of the matching item. |
typeOf() | - | Returns the name of the script as a symbol. |
-- "Xlist" parent script -- Author: Vladin M. Mitov -- May, 2011 -- Last Update - February, 2012 -- http://www.ed-multimedia.com -- EXAMPLES: ------------------------------ -- myList = script( "xList" ).new( 1, 2, 3 ) -- put myList.interface() -- myList.reverse() -- put myList.toString() -- "3,2,1" -- myList.add( 4, 5, 6 ) -- put myList.toString() -- "3,2,1,4,5,6" -- myList.sort() -- put myList.toString() -- "1,2,3,4,5,6" -- myList = script( "xList" ).new( 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 ) -- put myList.filter( #getEven ).toString() -- "2,4,6,8,10" -- A handler, defined in a movie script --on getEven( aelement ) -- return( aelement mod 2 = 0 ) --end getEven ------------------------------------------------- -- PROPERTIES ------------------------------------------------- on ___________________________PROPERTIES end property ancestor ------------------------------------------------- -- CONSTRUCTOR / DESTRUCTOR ------------------------------------------------- on ___________________________CONSTRUCTOR_DESTRUCTOR end on new( me ) ancestor = list() p = the paramCount repeat with i = 2 to p callAncestor( #add, me, param( i ) ) end repeat return me end new on dispose( me ) ancestor.deleteAll() ancestor = VOID end dispose ------------------------------------------------- -- PUBLIC METHODS ------------------------------------------------- on ___________________________PUBLIC_METHODS end on getAt( me, n ) if( n < 1 or n > count( ancestor ) ) then return VOID return ancestor[ n ] end getAt on deleteAt( me, n ) if( n < 1 or n > count( ancestor ) ) then return VOID callAncestor( #deleteAt, me, n ) return TRUE end deleteAt on lastIndexOf( me, searchElement, startIndex ) if( voidP( startIndex ) ) then startIndex = count( ancestor ) repeat with i = startIndex down to 1 if( ancestor[ i ] = searchElement ) then return i end if end repeat return VOID end lastIndexOf on add( me ) p = the paramCount repeat with i = 2 to p callAncestor( #add, me, param( i ) ) end repeat end add on addAt( me, pos, val ) if( voidP( pos ) ) then return FALSE if( pos < 1 ) then return FALSE if( voidP( val ) ) then return FALSE callAncestor( #addAt, me, pos, val ) end addAt on append( me ) p = the paramCount repeat with i = 2 to p callAncestor( #append, me, param( i ) ) end repeat end append on pop( me ) n = callAncestor( #getLast, me ) callAncestor( #deleteAt, me, count( ancestor ) ) return n end pop on shift( me ) e = callAncestor( #getAt, me, 1 ) callAncestor( #deleteAt, me, 1 ) return e end shift on unshift( me ) p = the paramCount repeat with i = p down to 2 callAncestor( #addAt, me, 1, param( i ) ) end repeat return count( ancestor ) end unshift on slice( me, startIndex, endIndex ) retval = me.script.new() p = the paramCount if( voidP( startIndex ) ) then s = 1 e = e = count( ancestor ) end if if( p = 2 ) then if( startIndex = 1 or startIndex = 0 ) then s = 1 e = count( ancestor ) else if( startIndex < 0 ) then e = count( ancestor ) s = startIndex + e + 1 else if( startIndex > 0 ) then s = startIndex e = count( ancestor ) end if else if( p = 3 ) then if( startIndex = 0 or endIndex = 0 ) then return retval else if( startIndex > 0 and endIndex < 0 ) then s = startIndex e = count( ancestor ) + endIndex + 1 else if( startIndex < 0 and endIndex > 0 ) then return retval else if( startIndex > 0 and endIndex > 0 ) then if( startIndex = endIndex ) then s = startIndex e = startIndex else if( startIndex > endIndex ) then return retval else if( startIndex < endIndex ) then s = startIndex e = endIndex end if else if( startIndex < 0 and endIndex < 0 ) then if( startIndex = endIndex ) then s = count( ancestor ) + startIndex + 1 e = s else if( startIndex > endIndex ) then return retval else if( startIndex < endIndex ) then s = count( ancestor ) + startIndex + 1 e = count( ancestor ) + endIndex + 1 end if end if end if repeat with i = s to e retval.add( ancestor[ i ] ) end repeat return retval end slice on splice( me, startIndex, deleteCount, values ) retval = me.script.new() p = the paramcount s = integer( startIndex ) if( voidp( s ) or s = 0 ) then s = 1 if( s < 0 ) then s = count( ancestor ) + s + 1 if( p = 1 ) then return retval else if( p <= 2 ) then e = count( ancestor ) else if( ilk( deleteCount ) <> #integer ) then deleteCount = 0 e = min( count( ancestor ), s + deleteCount - 1 ) end if repeat with i = e down to s retval.addAt( 1, ancestor[ i ] ) callAncestor( #deleteAt, me, i ) end repeat if( p < 4 ) then return retval repeat with j = p down to 4 xparam = param( j ) if( ilk( xparam ) = #list or ilk( xparam ) = #propList ) then cnt = count( xparam ) repeat with jj = cnt down to 1 callAncestor( #addAt, me, s, xparam[ jj ] ) end repeat else callAncestor( #addAt, me, s, xparam ) end if end repeat return retval end splice on some( me, ahandler, aobject ) if( voidP( aobject ) ) then aobject = _movie cnt = count( ancestor ) repeat with i = 1 to cnt element = ancestor[ i ] f = call( ahandler, aobject, element, i, me ) if( f = TRUE ) then return f end if end repeat return FALSE end some on every( me, ahandler, aobject ) if( voidP( aobject ) ) then aobject = _movie cnt = count( ancestor ) repeat with i = 1 to cnt element = ancestor[ i ] f = call( ahandler, aobject, element ) if( f = FALSE ) then return f end if end repeat return TRUE end every on filter( me, ahandler, aobject ) if( voidP( aobject ) ) then aobject = _movie cnt = count( ancestor ) retval = me.script.new() repeat with i = 1 to cnt element = ancestor[ i ] f = call( ahandler, aobject, element ) if( f = TRUE ) then retval.append( element ) end if end repeat return retval end filter on forEach( me, ahandler, aobject ) if( voidP( aobject ) ) then aobject = _movie cnt = count( ancestor ) repeat with i = cnt down to 1 element = ancestor[ i ] f = call( ahandler, aobject, element, i, me ) end repeat end forEach on map( me, ahandler, aobject ) if( voidP( aobject ) ) then aobject = _movie cnt = count( ancestor ) retval = me.script.new() repeat with i = 1 to cnt element = ancestor[ i ] retval.append( call( ahandler, aobject, element ) ) end repeat return retval end map on shuffle( me ) cnt = count( ancestor ) if ( cnt = 0 ) then return FALSE repeat while ( cnt > 0 ) j = random( cnt ) tempi = ancestor[ cnt ] tempj = ancestor[ j ] ancestor[ cnt ] = tempj ancestor[ j ] = tempi cnt = cnt - 1 end repeat return TRUE end shuffle on count( me ) if( voidP( ancestor ) ) then return VOID return count( ancestor ) end count on concat( me ) p = the paramCount t = callAncestor( #duplicate, me ) retval = me.script.new() repeat with i = 2 to p e = param( i ) if( ilk( e ) = #list ) then cnt = count( e ) repeat with j = 1 to cnt t.append( e[ j ] ) end repeat else t.append( e ) end if end repeat retval.ancestor = t return retval end concat on reverse( me ) left = 1 right = count( ancestor ) repeat while( left < right ) temp = ancestor[ left ] ancestor[ left ] = ancestor[ right ] ancestor[ right ] = temp left = left + 1 right = right - 1 end repeat end reverseList on join( me, sep ) t = EMPTY cnt = count( ancestor ) repeat with i = 1 to cnt put ancestor[ i ] & sep after t end repeat len = t.length reallength = ( len - sep.length ) + 1 repeat with j = len down to reallength delete t.char[ t.length ] end repeat return t end join on toString( me ) t = me.join( "," ) return t end toString on sort( me, order ) if( voidP( order ) or [#ASC, #DESC].getPos( order ) = 0 ) then order = #ASC case( order ) of #ASC : callAncestor( #sort, me ) #DESC: callAncestor( #sort, me ) me.reverse() end case end sort on sortOn( me, columntoSortOn, order ) if ( ilk( ancestor ) <> #list ) then return FALSE if ( count( ancestor ) = 0 ) then return FALSE if ( ilk( ancestor[1] ) <> #list ) then return FALSE if( voidP( order ) or [#ASC, #DESC].getPos( order ) = 0 ) then order = #ASC case( order ) of #ASC :__sort_on_internal_ASC( me, columntoSortOn ) #DESC:__sort_on_internal_DESC( me, columntoSortOn ) end case end sortOn on is( me, atype ) obj = me types = [ #list, #xlist ] t = obj.typeOf() repeat while t <> #xlist types.append( t ) obj = obj.getAprop( #ancestor ) t = obj.typeOf() end repeat put types return( types.getPos( atype ) > 0 ) end is on typeOf( me ) the itemdelimiter = quote return symbol( string( me ).item[ 2 ] ) end typeOf on interface( me ) msg = EMPTY put "new( {...args} ) -- Returns a new list, you can specify the initial values as arguments." & RETURN after msg put "dispose() -- Destroys the list" & RETURN after msg put "shuffle() -- Shuffles the list values in-place, using Fisher–Yates algorithm." & RETURN after msg put "add( {...args} )* -- Adds values to a list. For a sorted list, the values are placed in their proper order." & RETURN after msg put "getAt()* -- Prevents ""e&"Index out of range""e&" exception." & RETURN after msg put "deleteAt()* -- Prevents ""e&"Index out of range""e&" exception." & RETURN after msg put "append( {...args} )* -- Adds the specified values to the end of a list." & RETURN after msg put "shift() -- Removes the first element from an array and returns that element." & RETURN after msg put "pop() -- Removes the last element from a list and returns the value of that element." & RETURN after msg put "unshift( ...args ) -- Adds one or more elements to the beginning of a list and returns the new count of the list." & RETURN after msg put "slice( startIndex, endIndex ) -- Returns a new list that consists of a range of elements from the original list, without modifying the original list." & RETURN after msg put "splice( startIndex, deleteCount{, ... values} ) -- Adds elements to and removes elements from a list." & RETURN after msg put "some( handler{, object} ) -- Executes a test function on each item in the list until an item is reached that returns TRUE." & RETURN after msg put "every( handler{, object} ) -- Executes a test handler on each item in the list until an item is reached that returns FALSE for the specified handler." & RETURN after msg put "filter( handler{, object} ) -- Executes a test handler on each item in the list and constructs a new list for all items that return TRUE for the specified handler." & RETURN after msg put "forEach( handler{, object} ) -- Executes a handler on each item in the list." & RETURN after msg put "map( handler{, object} ) -- Executes a handler on each item in a list, and constructs a new list of items corresponding to the results of the handler on each item in the original list." & RETURN after msg put "sort( {symbolOrder} ) -- Sorts the list ascending or descending ( #ASC / #DESC )" & RETURN after msg put "sortOn( intColumnIndex{, symbolOrder} ) -- Sorts the list on given ""e&"column""e&"( #ASC or #DESC )." & RETURN after msg put "concat() -- Concatenates the elements specified in the parameters with the elements in a list and creates a new list." & RETURN after msg put "reverse() -- Reverses the list in-place." & RETURN after msg put "join( separator ) -- Returns a string, constructed by items in the list, with the separator inserted between them." & RETURN after msg put "toString() -- Returns a string that represents the elements in the specified list, separated by commas." & RETURN after msg put "lastIndexOf( searchElement, startIndex ) -- Searches for an item in a list, working backward from the last item, and returns the index position of the matching item." & RETURN after msg put "typeOf() -- Returns the name of the script as a symbol." & RETURN after msg put "is()" after msg return msg end interface ------------------------------------------------- -- PRIVATE METHODS ------------------------------------------------- on ___________________________PRIVATE_METHODS end on __sort_on_internal_ASC( me, c ) t = list() t[ c ] = 0 ancestor.add( t ) cnt = count( ancestor ) repeat with i = cnt down to 0 flipped = FALSE j = 0 repeat while j < i j = j + 1 if ( j + 1 < cnt ) then aInt = float( ancestor[ j ][ c ] ) bInt = float ( ancestor[ j + 1 ][ c ] ) if ( aInt > bInt ) then t = ancestor[ j ] ancestor[ j ] = ancestor[ j + 1 ] ancestor[ j + 1 ] = t flipped = TRUE end if end if end repeat end repeat ancestor.deleteAt( cnt ) return TRUE end __sort_on_internal_ASC on __sort_on_internal_DESC( me, c ) t = list() t[ c ] = 0 ancestor.add( t ) cnt = count( ancestor ) repeat with i = cnt down to 0 flipped = FALSE j = 0 repeat while j < i j = j + 1 if ( j + 1 < cnt ) then aInt = float( ancestor[ j ][ c ] ) bInt = float ( ancestor[ j + 1 ][ c ] ) if ( aInt < bInt ) then t = ancestor[ j ] ancestor[ j ] = ancestor[ j + 1 ] ancestor[ j + 1 ] = t flipped = TRUE end if end if end repeat end repeat ancestor.deleteAt( cnt ) return TRUE end __sort_on_internal_DESC on ___________________________END_XLIST end
An example of filter() method:
myList = script( "xList" ).new( 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 ) put myList.filter( #getEven ).toString() -- "2,4,6,8,10" -- A handler, defined in a movie script: on getEven( aelement ) return( aelement mod 2 = 0 ) end getEven
Added sort() method.