Two dimensional Array in Apple script

Is there any way to create two dimensional array in Apple script? If not, what is the other for creating it ?

Vanilla AppleScript does not understand “array”, it has only lists and records. There are third-party osaxen that know about arrays, however. The “purest” way to handle arrays is to make lists within lists: {{a1, a2, a3}, {b1, b2, b3}, {c1, c2, c3}} for example.

The Satimage osax supports arrays, I think – I haven’t used it for that.

I took this opportunity to get a better understanding of applescript.
Here is an array script object that I put together.
I have not tested it much and it may have some holes in it.
Feedback about it’s viability would be great. Also would be good to know
if I’m doing anything that is dumb or can be improved on. I’ve been scripting for
a couple weeks and I am still struggling with the basic syntax and vocabulary.


(*
Multi-Dimensional Array script object
 
makeArray(theDimensionsList) - makes a multi-dimensional array
	
	param: theDimensionsList - list of numbers indicating the size of each dimension
						(numbers as text ok)
 	returns: an array script object
	errors: throws error if theDimensionsList is invalid (bad numbers, non list, empty)
	example:  set myArray to makeArray({3,4})
			 set myArray to makeArray({"3","4"})

putItem(anItem, aLocation) - stores an item in the array
	param: anItem - any item
	param: aLocation - is a list of indexes within the orginal dimensions of the array
				(numbers as text ok)
	returns: the anItem object
	errors: throws an error if location is invalid (bad numbers, non list, out of range)
	example: tell myArray to putItem("Fred", {2,1})

getItem(aLocation) - retrieve an item from the array
	param: aLocation - is a list of indexes within the orginal dimensions of the array
					(numbers as text ok)
	returns: the item or 'missing item' if the cell is empty
	errors: throws an error if location is invalid (bad numbers, non list, out of range)
	example: set myItem to myArray's getItem({2,1})
*)

on makeArray(theDimensionsList)
	script
		property dimensionsList : theDimensionsList
		property arrayList : {}
		
		-------------------- public handlers -------------------------
		
		on getItem(aLocation)
			__checkLoc__(aLocation)
			set anItem to __get__(arrayList, aLocation)
			if anItem is {} then return missing value
			return item 1 of anItem
		end getItem
		
		on putItem(anItem, aLocation)
			__checkLoc__(aLocation)
			return __put__(arrayList, anItem, aLocation)
		end putItem
		
		---------------------- private handlers ------------------------
		-- initalize array emtpy lists
		on __init__()
			set ok to true
			if class of dimensionsList is list and list is not {} then
				repeat with i from 1 to count of dimensionsList
					set n to (item i of dimensionsList) as integer
					if n < 1 then
						set ok to false
						exit repeat
					end if
				end repeat
			else
				set ok to false
			end if
			if (ok is false) then
				error "Invalid array dimensions." number -10100
			end if
			__alloc__(arrayList, dimensionsList)
		end __init__
		
		-- recursive allocation primitive
		on __alloc__(array, dims)
			set numDims to count of dims
			if numDims is 0 then return
			repeat first item of dims times
				set end of array to {}
				if (count of dims) > 1 then
					__alloc__(last item of array, items 2 thru end of dims)
				end if
			end repeat
		end __alloc__
		
		-- get cell primitive
		on __get__(aList, aLoc)
			set curList to item (item 1 of aLoc) of aList
			if (count of aLoc) is 1 then
				return curList
			end if
			return __get__(curList, items 2 thru end of aLoc)
		end __get__
		
		-- put cell primitive
		on __put__(aList, anItem, aLoc)
			if (count of aLoc) is 1 then
				set item (item 1 of aLoc) of aList to {anItem}
				return anItem
			end if
			return __put__(item (item 1 of aLoc) of aList, anItem, items 2 thru end of aLoc)
		end __put__
		
		-- error check on location parameter - throws -10101 error number
		on __checkLoc__(aLoc)
			set ok to true
			if class of aLoc is not list or (count of aLoc) is not (count of dimensionsList) then
				set ok to false
			else
				repeat with i from 1 to count of dimensionsList
					set n to (item i of aLoc) as integer
					
					if n < 1 or n > item i of the dimensionsList then
						set ok to false
						exit repeat
					end if
				end repeat
			end if
			if (ok is false) then
				error "Invalid array location." number -10101
			end if
		end __checkLoc__
	end script
	
	-- initialization code
	set theArray to result
	tell theArray to __init__()
	return theArray
end makeArray


-------------------
--  More examples
-------------------

set x to makeArray({2, 3})
--> «script»
get x's dimensionsList
--> {2, 3}
get x's arrayList
--> {{{}, {}, {}}, {{}, {}, {}}}
set loc to {1, "2"} -- note text of valid number is ok
try
	tell x to putItem({"yee"}, loc)
	--> {"yee"}
	tell x to getItem(loc)
	--> {"yee"}
	x's putItem("fap", loc)
	--> "fap"
	x's getItem(loc)
	--> "fap"
	x's getItem({2, 2})
	--> missing value
	x's getItem({0, 40, "x2"})
	--> throws err if wrong number of indexes,
	--  index too low or high, or index is not a number
on error msg number n
	display alert msg & " Error # " & n
	--> "Invalid array location. Error # -10101"
end try

whooie- thats cool stuff!

Great stuff! That’s a nice clean solution.

You might be interested in Deivy Petrescu’s library script in http://ScriptBuilders.net, namely his Matemática Matrices, about which he says:

This is a library in editable form that could easily be adopted to your notation here by changing very little of the library.