AppleScript Library

List Library

   The list library contains a bunch of handy functions to manipulate and analyze AppleScript lists.

All handlers displayed on this page were freely available on the internet or written by myself. Please refer to the copyright section at the end of this page. Feedback appreciated.


AppleScript Editor open download

Properties
myName
General
isAllSameClass
isAllOfClass
isAllNumbers
isAllText
makeList
multiplyList
Manipulation
insertItem
deleteItem
chopList
removeDuplicates
replaceMatches
Locating
findFirst
findLast
findAll
countMatches
Sorting
sortList
unsortList
Ordered Lists
mergeLists
Grouping
groupList
ungroupList
interlaceLists
deinterlaceList

Properties

property myName

Name that should be used when loading this library.

show source AppleScript-Editor open insert append toc
property myName : "_list"

General

isAllSameClass(lst)

Checks if all list items are of the same class.

lstlist
boolean

Written by:HAS

Example:

isAllSameClass({1, 2, 3}) 
--> true
show source AppleScript Editor open insert append toc
on isAllSameClass(lst)
	local lst, len, itemsClass
	try
		if lst's class is not list then error "not a list." number -1704
		set len to count lst
		if len > 0 then
			set itemsClass to class of item 1 of lst
			return (count lst each itemsClass) = len
		else
			return true
		end if
	on error eMsg number eNum
		error "Can't check isAllSameClass: " & eMsg number eNum
	end try
end isAllSameClass

isAllOfClass(lst, theClass)

Checks if all list items are of a specific class.

lstlist
theClassclassinteger/real/string/list/etc.
boolean

Written by:HAS

Example:

isAllOfClass({1, 2, 3}, integer) 
--> true
show source AppleScript Editor open insert append toc
on isAllOfClass(lst, theClass)
	local lst, theClass
	try
		if lst's class is not list then error "not a list." number -1704
		return (count lst each theClass) = (count lst)
	on error eMsg number eNum
		error "Can't check isAllOfClass: " & eMsg number eNum
	end try
end isAllOfClass

isAllNumbers(lst)

Checks if all list items are numbers (integer or real)

lstlist
boolean

Written by:HAS

Example:

isAllNumbers({1, 2, 3}) 
--> true
show source AppleScript Editor open insert append toc
on isAllNumbers(lst)
	local lst
	try
		if lst's class is not list then error "not a list." number -1704
		return (count lst each number) = (count lst)
	on error eMsg number eNum
		error "Can't check isAllNumbers: " & eMsg number eNum
	end try
end isAllNumbers

isAllText(lst)

Checks if all list items are text values (string or unicode)

lstlist
boolean

Written by:HAS

Example:

isAllText({"a", "b", "c"}) 
--> true
show source AppleScript Editor open insert append toc
on isAllText(lst)
	local lst
	try
		if lst's class is not list then error "not a list." number -1704
		return (count lst each string) = (count lst)
	on error eMsg number eNum
		error "Can't check isAllText: " & eMsg number eNum
	end try
end isAllText

makeList(len, val)

Make a filled list.

lenintegerlength of list
valanythingvalue to fill list with
list

Written by:HAS

Example:

makeList(3, 1) 
--> {1, 1, 1}
show source AppleScript Editor open insert append toc
on makeList(len, val)
	-- acknowlegement: Arthur J Knapp, who severely 
	-- performance-optimised the basic algorithm
	local len, val, lstCpy
	try
		set len to len as integer
		if len < 1 then error "length must be greater than 0." number -1704
		script k
			property lst : {val}
		end script
		if val's class is in {class, constant, boolean, integer, real, string, ¬
			Unicode text} then
			-- duplicate using set instead of copy (faster)
			repeat while ((count of k's lst) < len)
				script
					property lst : k's lst & k's lst
				end script
				set k to result
			end repeat
		else
			-- duplicate using copy to prevent data sharing 
			-- between list's items
			copy k to k
			repeat while ((count of k's lst) < len)
				copy k's lst to lstCpy
				script
					property lst : k's lst & lstCpy
				end script
				set k to result
			end repeat
		end if
		return k's lst's items 1 thru len
	on error eMsg number eNum
		error "Can't makeList: " & eMsg number eNum
	end try
end makeList

multiplyList(lst, n)

Returns a list repeating the input list n times.

lstlist
nintegernumber of times to repeat
list

Written by:HAS

Example:

multiplyList({1, 2, 3}, 3) 
--> {1, 2, 3, 1, 2, 3, 1, 2, 3}
show source AppleScript Editor open insert append toc
on multiplyList(lst, n)
	local lst, len, n, mk
	try
		if lst's class is not list then error "not a list." number -1704
		set n to n as integer
		if n < 1 then return {}
		set len to n * (count lst)
		set mk to 1
		repeat until mk is greater than or equal to n
			set lst to lst & lst
			set mk to mk * 2
		end repeat
		return lst's items 1 thru len
	on error eMsg number eNum
		error "Can't multiplyList: " & eMsg number eNum
	end try
end multiplyList

Manipulation

insertItem(lst, val, idx)

Insert an item into a list.

lstlist
valanythingthe value to add
idxintegerindex of item to insert after (notes: 0 inserts before first item; negative indexes allowed)
list

Written by:HAS

Example:

insertItem({"a", "b", "c", "d"}, true, 3) 
--> {"a", "b", "c", true, "d"}
show source AppleScript Editor open insert append toc
on insertItem(lst, val, idx)
	local lst, val, idx, ndx, l
	try
		if lst's class is not list then error "not a list." number -1704
		set ndx to idx as integer
		script k
			property l : lst
		end script
		set len to count k's l
		if ndx < 0 then
			set ndx to len + ndx + 1
			if ndx < 0 then error "index " & idx & " is out of range."
		end if
		if ndx is 0 then
			return {val} & lst
		else if ndx is len then
			return lst & {val}
		else if ndx < len then
			return (lst's items 1 thru ndx) & {val} & ¬
				(lst's items (ndx + 1) thru -1)
		else
			error "index " & idx & " is out of range."
		end if
	on error eMsg number eNum
		error "Can't insertItem: " & eMsg number eNum
	end try
end insertItem

deleteItem(lst, idx)

Delete an item from a list.

lstlist
idxintegerindex of item to delete (note: negative indexes allowed)
list

Written by:HAS

Example:

deleteItem({1, 2, 3}, 2) 
--> {1, 3}
show source AppleScript Editor open insert append toc
on deleteItem(lst, idx)
	local lst, idx, len, ndx, l
	try
		if lst's class is not list then error "not a list." number -1704
		script k
			property l : lst
		end script
		set len to count of k's l
		set ndx to idx as integer
		if ndx is 0 then
			error "index 0 is out of range." number -1728
		else if ndx < 0 then
			set ndx to len + 1 + ndx
			if ndx < 1 then error "index " & idx & ¬
				" is out of range." number -1728
		else if ndx > len then
			error "index " & idx & " is out of range." number -1728
		end if
		if ndx is 1 then
			return rest of k's l
		else if ndx is len then
			return k's l's items 1 thru -2
		else
			return (k's l's items 1 thru (ndx - 1)) & ¬
				(k's l's items (ndx + 1) thru -1)
		end if
	on error eMsg number eNum
		error "Can't deleteItem: " & eMsg number eNum
	end try
end deleteItem

chopList(lst)

Chop last item from a list (opposite of 'rest of lst').

lstlist
list

Written by:HAS

Example:

chopList({1, 2, 3}) 
--> {1, 2}
show source AppleScript Editor open insert append toc
on chopList(lst)
	local lst
	try
		return reverse of rest of reverse of lst
	on error eMsg number eNum
		if lst's class is not list then set {eMsg, eNum} to ¬
			{"not a list.", -1704}
		error "Can't chopList: " & eMsg number eNum
	end try
end chopList

removeDuplicates(lst)

Remove duplicate items from a list (respects current considering/ignoring settings).

lstlist
list

Written by:HAS

Example:

removeDuplicates({1, 2, 2, 3, 1}) 
--> {1, 2, 3}
show source AppleScript Editor open insert append toc
on removeDuplicates(lst)
	local lst, itemRef, res, itm
	try
		if lst's class is not list then error "not a list." number -1704
		script k
			property l : lst
			property res : {}
		end script
		repeat with itemRef in k's l
			set itm to itemRef's contents
			-- note: minor speed optimisation when removing duplicates 
			-- from ordered lists: assemble new list in reverse so 
			-- 'contains' operator checks most recent item first
			if k's res does not contain {itm} then ¬
				set k's res's beginning to itm
		end repeat
		return k's res's reverse
	on error eMsg number eNum
		error "Can't removeDuplicates: " & eMsg number eNum
	end try
end removeDuplicates

replaceMatches(lst, match_val, repl_val, bool_repl_all)

Replaces the first occurrence or all occurrences of a value.

lstlist
match_valanythingvalue to match
repl_valanythingnew value to use
bool_repl_allbooleanreplace all values?
list

Written by:ljr

Example:

replaceMatches({1, 2, 3, 1}, 1, 5, false) 
--> {5, 2, 3, 1}
show source AppleScript Editor open insert append toc
on replaceMatches(lst, match_val, repl_val, bool_repl_all)
	local lst, match_val, repl_val, bool_repl_all, len, newList, this_item, i
	try
		if lst's class is not list then error "not a list." number -1704
		script k
			property l : lst
		end script
		set len to count k's l
		set newList to {}
		repeat with i from 1 to len
			set this_item to k's l's item i
			if this_item is match_val then
				set end of newList to repl_val
				if bool_repl_all is false then
					repeat with i from (i + 1) to len
						set this_item to k's l's item i
						set end of newList to this_item
					end repeat
					return newList
				end if
			else
				set end of newList to this_item
			end if
		end repeat
		return newList
	on error eMsg number eNum
		error "Can't replaceMatches: " & eMsg number eNum
	end try
end replaceMatches

Locating

findFirst(lst, val)

Get index of first item that matches value.

lstlist
valanythingthe value to find
integeritem's offset, or 0 if not found

Written by:HAS

Example:

findFirst({1, 5, 8, 9}, 8) 
--> 3
show source AppleScript Editor open insert append toc
on findFirst(lst, val)
	local lst, val, i
	try
		if lst's class is not list then error "not a list." number -1704
		if {val} is not in lst then return 0
		script k
			property l : lst
		end script
		repeat with i from 1 to count of k's l
			if k's l's item i is val then return i
		end repeat
	on error eMsg number eNum
		error "Can't findFirst: " & eMsg number eNum
	end try
end findFirst

findLast(lst, val)

Get index of last item that matches value.

lstlist
valanythingthe value to find
integeritem's offset from end of list (negative), or 0 if not found

Dependencies: findFirst

Written by:HAS

Example:

findLast({8, 5, 8, 9}, 8) 
--> -2
show source AppleScript Editor open insert append toc
on findLast(lst, val)
	local lst, val
	try
		if lst's class is not list then error "not a list." number -1704
		return -(my findFirst(lst's reverse, val))
	on error eMsg number eNum
		error "Can't findLast: " & eMsg number eNum
	end try
end findLast

findAll(lst, val)

Get index of all items that match value.

lstlist
valanythingthe value to find
listindexes of matching items

Written by:HAS

Example:

findAll({8, 5, 8, 9}, 8) 
--> {1, 3}
show source AppleScript Editor open insert append toc
on findAll(lst, val)
	local lst, val, res
	try
		if lst's class is not list then error "not a list." number -1704
		if {val} is not in lst then return {}
		set res to {}
		script k
			property l : lst
		end script
		repeat with i from 1 to count of k's l
			if k's l's item i is val then set res's end to i
		end repeat
		return res
	on error eMsg number eNum
		error "Can't findAll: " & eMsg number eNum
	end try
end findAll

countMatches(lst, val)

Get number of occurrences of a specific item.

lstlist
valanythingthe value to match
integer

Written by:ljr

Example:

countMatches({8, 5, 8, 9}, 8) 
--> 2
show source AppleScript Editor open insert append toc
on countMatches(lst, val)
	local lst, val, counter
	try
		if lst's class is not list then error "not a list." number -1704
		script k
			property l : lst
		end script
		set len to count k's l
		set counter to 0
		repeat with i from 1 to len
			if k's l's item i is val then set counter to counter + 1
		end repeat
		return counter
	on error eMsg number eNum
		error "Can't countMatches: " & eMsg number eNum
	end try
end countMatches

Sorting

sortList(lst)

Sort a list (Respects current considering/ignoring settings). Will raise error if list contains both text and numbers, as text and numerical values cannot be reliably compared against one another.

lstlistlist of simple, directly comparable values (integers/reals/string/date)
list

Written by:HAS

Example:

sortList({3, 1, 2}) 
--> {1, 2, 3}
show source AppleScript Editor open insert append toc
on sortList(theList)
	-- a stack-based, non-recursive quicksort
	local theList, s, l, a, b, c, j, r, v, i, tmp
	try
		if theList's class is not list then error "not a list." number -1704
		if (count theList each number) > 0 and ¬
			((count theList each string) > 0) then
			error "can't sort a list containing both " & ¬
				"number and text values." number -1704
		end if
		script k -- list access speed kludge
			property lst : theList's items
		end script
		if k's lst's length < 2 then return k's lst
		set s to {a:1, b:count k's lst, c:missing value} -- unsorted slices stack
		repeat until s is missing value
			set l to s's a
			set r to s's b
			set s to get s's c
			set i to l
			set j to r
			set v to k's lst's item ((l + r) div 2)
			repeat while (j > i)
				repeat while (k's lst's item i < v)
					set i to i + 1
				end repeat
				repeat while (k's lst's item j > v)
					set j to j - 1
				end repeat
				if (ij) then
					set tmp to k's lst's item i
					set k's lst's item i to k's lst's item j
					set k's lst's item j to tmp
					set i to i + 1
					set j to j - 1
				end if
			end repeat
			if (l < j) then set s to {a:l, b:j, c:s}
			if (r > i) then set s to {a:i, b:r, c:s}
		end repeat
		return k's lst
	on error eMsg number eNum
		error "Can't sortList: " & eMsg number eNum
	end try
end sortList

unsortList(lst)

Randomly rearrange a list.

lstlist
list

Written by:HAS

Example:

unsortList({1, 2, 3, 4}) 
--> {2, 3, 1, 4}
show source AppleScript Editor open insert append toc
on unsortList(lst)
	local lst, len, lastNum, idx1, idx2
	try
		if lst's class is not list then error "Not a list." number -1704
		script k
			property l : lst's items
		end script
		set len to count k's l
		-- calling osax only once improves overall performance approx 40%
		set lastNum to random number from 1 to 9.999999999971E+12
		repeat with idx1 from 1 to len
			set lastNum to (lastNum * 67128023) mod 9.999999999971E+12
			set idx2 to (lastNum mod len) + 1
			set tmp to k's l's item idx1
			set k's l's item idx1 to (get k's l's item idx2)
			set k's l's item idx2 to tmp
		end repeat
		return k's l
	on error eMsg number eNum
		error "Can't unsortList: " & eMsg number eNum
	end try
end unsortList

Ordered Lists

mergeLists(lst1, lst2)

Merge the contents of two ordered lists into one. All values in lists must be directly comparable to one another

lst1listan ordered list
lst2listan ordered list
listan ordered list

Written by:HAS

Example:

mergeLists({1, 3, 5}, {2, 4, 8}) 
--> {1, 2, 3, 4, 5, 8}
show source AppleScript Editor open insert append toc
on mergeLists(lst1, lst2)
	local lst1, lst2, itm1, itm2, len1, len2, i, j, res
	try
		if lst1's class is not list then ¬
			error "lst1 parameter isn't a list." number -1704
		if lst2's class is not list then ¬
			error "lst2 parameter isn't a list." number -1704
		script k
			property l1 : lst1
			property l2 : lst2
		end script
		set len1 to count k's l1
		set len2 to count k's l2
		if len1 is 0 then return lst2
		if len2 is 0 then return lst1
		set itm1 to k's l1's item 1
		set itm2 to k's l2's item 1
		set i to 2
		set j to 2
		set res to {}
		repeat
			if itm2 is less than itm1 then
				set res's end to itm2
				if j > len2 then
					set res to res & k's l1's items (i - 1) thru -1
					exit repeat
				else
					set itm2 to k's l2's item j
					set j to j + 1
				end if
			else
				set res's end to itm1
				if i > len1 then
					set res to res & k's l2's items (j - 1) thru -1
					exit repeat
				else
					set itm1 to k's l1's item i
					set i to i + 1
				end if
			end if
		end repeat
		return res
	on error eMsg number eNum
		error "Can't mergeLists: " & eMsg number eNum
	end try
end mergeLists

Grouping

groupList(lst, groupLen)

Group a list's items.

lstlist
groupLenintegermax number of items per group (note that last group may be shorter than others)
list of sublists

Written by:HAS

Example:

groupList({1, 2, 3, 4, 5, 6}, 2) 
--> {{1, 2}, {3, 4}, {5, 6}}
show source AppleScript Editor open insert append toc
on groupList(lst, groupLen)
	local lst, tailLen, groupLen, idx
	try
		if lst's class is not list then error "not a list." number -1704
		script k
			property l : lst
			property res : {}
		end script
		set tailLen to (count of k's l) mod groupLen
		repeat with idx from 1 to ((count of k's l) - tailLen) by groupLen
			set k's res's end to k's l's items idx thru (idx + groupLen - 1)
		end repeat
		if tailLen is not 0 then
			set k's res's end to k's l's items -tailLen thru -1
		end if
		return k's res
	on error eMsg number eNum
		error "Can't groupList: " & eMsg number eNum
	end try
end groupList

ungroupList(lst)

Flatten sublists.

lstlist of sublists
list

Written by:HAS

Example:

ungroupList({{1, 2, 3}, {4, 5, 6}}) 
--> {1, 2, 3, 4, 5, 6}
show source AppleScript Editor open insert append toc
on ungroupList(lst)
	local lst, res, itemRef
	try
		if lst's class is not list then error "not a list." number -1704
		script k
			property l : lst
		end script
		if (count k's l each list) is not (count k's l) then ¬
			error "list contains non-list items." number -1704
		set res to {}
		repeat with itemRef in k's l
			set res to res & itemRef's contents
		end repeat
		return res
	on error eMsg number eNum
		error "Can't ungroupList: " & eMsg number eNum
	end try
end ungroupList

interlaceLists(list1, list2)

Interlace items from two equal-length lists.

list1list
list2list
list

Written by:HAS

Example:

interlaceLists({1, 2, 3}, {4, 5, 6}) 
--> {1, 4, 2, 5, 3, 6}
show source AppleScript Editor open insert append toc
on interlaceLists(list1, list2)
	local list1, list2
	try
		if list1's class is not list then error "not a list." number -1704
		if list2's class is not list then error "not a list." number -1704
		script k
			property l1 : list1
			property l2 : list2
			property res : {}
		end script
		if (count of k's l1) is not (count of k's l2) then error "lists are different lengths."
		repeat with i from 1 to count k's l1
			set k's res's end to k's l1's item i
			set k's res's end to k's l2's item i
		end repeat
		return k's res
	on error eMsg number eNum
		error "Can't interlaceLists: " & eMsg number eNum
	end try
end interlaceLists

deinterlaceList(lst)

Separate alternating items into two lists.

lstlist
list containing two lists

Written by:HAS

Example:

deinterlaceList({1, 2, 3, 4, 5, 6}) 
--> {{1, 3, 5}, {2, 4, 6}}
show source AppleScript Editor open insert append toc
on deinterlaceList(lst)
	local lst
	try
		if lst's class is not list then error "not a list." number -1704
		script k
			property l : lst
			property l1 : {}
			property l2 : {}
		end script
		if (count k's l) mod 2 is not 0 then error "list is not an even length."
		repeat with i from 1 to count of k's l by 2
			set k's l1's end to k's l's item i
			set k's l2's end to k's l's item (i + 1)
		end repeat
		return {k's l1, k's l2}
	on error eMsg number eNum
		error "Can't deinterlaceList: " & eMsg number eNum
	end try
end deinterlaceList

Copyright

© 2003 HAS (http://applemods.sourceforge.net)
isAllSameClass, isAllOfClass, isAllNumbers, isAllText, makeList, multiplyList, insertItem, deleteItem, chopList, removeDuplicates, findFirst, findLast, findAll, sortList, unsortList, mergeLists, groupList, ungroupList, interlaceLists, deinterlaceList
© 2008 ljr (http://applescript.bratis-lover.net)
replaceMatches, countMatches

Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:

The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON INFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.

Note:
Some of HAS's functions have been modified since Applescript does no longer distinguish between string, text or Unicode classes. [ljr]