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.