Looks like no one’s replied in a while. To start the conversation again, simply ask a new question.

Set an indeterminate number of variables

Hi fellow scriptologists... I thought I was good at this but I'm not as good as I thought I was...


I need to create a number of variables (Variable1, Variable2 etc) based on the contents of a list of indeterminate length - headings of a document that's likely to change each time it's run. I'd like to assign a name to each variable that reflects its initial value ("Camera", "Shot", "Take", "Slate") although generic names would do, but my impression is that there's no way to ascribe a string to a variable name based on anything done within the script - you simply have to name it or you end up redefining another variable. And if you don't know how many you need, do you need to declare them all up front in order to be able to set them as required?


There may be a way, but I can't figure out how... any input appreciated.

Posted on Apr 17, 2015 11:17 PM

Reply
3 replies

Apr 18, 2015 5:26 AM in response to Peter Barrett

You can create arbitrary names for the keys in a record/dictionary using Cocoa via AppleScriptObj-C, but in regular AppleScript variable names are evaluated at compile time, so it's not really possible to create them when the script is run. Depending on exactly what you are wanting to do, a solution would be to use a list (or a list of records), and index into the list.

Apr 18, 2015 11:53 AM in response to Peter Barrett

Hello


You might be looking for something like hash table perhaps? Unlike other modern scripting languages, AppleScript has never had built-in hash table. Here's some options.


Option 1. Use unnamed collection in lieu of named variables. This is straightforward method which should suffice in most cases.


E.g., use:


set vars to {1, 2, 3, 4, 5}



in lieu of:


set var1 to 1 set var2 to 2 set var3 to 3 set var4 to 4 set var5 to 5




Option 2. Implement your own hash table (associative array) if you really want to.


E.g.,


set h to assoc()'s new(127) h's store({"var1", 1, "var2", 2, "var3", 3, "var4", 4, "var5", 5}) --return h's ht --return h's fetch("var4") return h's fetch({"var3", "var5"}) on assoc() script o property name : "assoc" property version : "0.12" property ht : {} -- ht entry is {} or list of {key, value} property sz : 0 -- given in new(); prime number for better performance property xx : {} property cc : {} on hash(s) (* anything s : key coercible to string return integer : hash code *) set cc to (s as string)'s id as list -- OS X 10.5 or later set result to 73 repeat with c in my cc (result * 37 + c) mod 1048573 as integer end repeat result mod sz + 1 as integer end hash on fetch(argv) (* anything or list argv : key or list of keys (key can be anything coercible to string) return anything or list : value or list of values associated with given key(s) (returns missing value for non-existent key) *) if argv's class = list then set xx to {} repeat with a in argv set my xx's end to fetch(a's contents) end repeat return my xx's contents else repeat with h in my ht's item hash(argv) -- linear search in collision if h's item 1 is argv then return h's item 2 end repeat return missing value end if end fetch on store(argv) (* list argv : {key, value} pair or {key1, value1, key2, value2, ...} pairs return list : for given pair {k, v}, {k, v} if k does not exist in table; or {{k, v}, {k, v1}} if k exists in table, where v1 is old value for k *) local argc set argc to count argv if argc > 2 and argc mod 2 = 0 then set xx to {} repeat with i from 1 to argc by 2 set my xx's end to store(argv's items i thru (i + 1)) end repeat return my xx's contents else if argc = 2 then -- separate chaining local p, v1 set {k, v} to argv set p to hash(k) repeat with h in my ht's item p -- linear search in collision if h's item 1 = k then set v1 to h's item 2 set h's item 2 to v return {{k, v}, {k, v1}} -- {new entry, old entry} end if end repeat set end of my ht's item p to {k, v} else error my name & "::store(): odd number of arguments." number 8001 end if end store on scratch(argv) (* anything or list argv : key or list of keys to delete return anything or list : value or list of values associated with deleted key(s) (returns missing value for non-existent key) *) if argv's class = list then set xx to {} repeat with a in argv set my xx's end to scratch(a's contents) end repeat return my xx's contents else -- delete key and return key's value if any local p, v, h set p to hash(argv) repeat with i from 1 to count my ht's item p -- linear search in collision set h to my ht's item p's item i if h's item 1 = argv then set v to h's item 2 set my ht's item p's item i to false set my ht's item p to my ht's item p's lists return v -- key's value end if end repeat return missing value end if end scratch on keys() (* return list : list of stored keys (in internal storage order) *) set xx to {} repeat with p in my ht repeat with h in p set end of my xx to h's item 1 end repeat end repeat return my xx's contents end keys on values() (* return list : list of stored values (in internal storage order) *) set xx to {} repeat with p in my ht repeat with h in p set end of my xx to h's item 2 end repeat end repeat return my xx's contents end values on new(m) (* integer m : size of hash table to be created (prime number for better performance) return script : initialized hash table object *) if m's class is integer and m > 0 then set sz to m repeat sz times set end of my ht to {} end repeat return o else error my name & "::new(): invalid size." number 8000 end if end new end script end assoc




Regards,

H

Set an indeterminate number of variables

Welcome to Apple Support Community
A forum where Apple customers help each other with their products. Get started with your Apple ID.