Use a variable as a key to index into an associative array?

Hello all,

Ok, so I’ve been a C programmer for years and in the past few years became a PHP programmer as well.

And in these languages it’s easy to create an associative array that you could index into with a variable:

PHP:
$key_var= ‘apple’;
$another_var = ‘apple’;
$some_array[$key_var] = ‘script’;
$this_variable = $some_array[$another_var];

$this_variable would equal ‘script’

simple, right?

So how is this done in applescript?

The AppleScript objects which are the most similar to associative arrays are (lists of) records:

set myFruits to {{fruit:"banana", fruitcolor:"yellow"}, {fruit:"strawberry", fruitcolor:"red"}, {fruit:"apple", fruitcolor:"green"}}

set theColor to "yellow"

repeat with f in myFruits
	if (fruitcolor of f = theColor) then
		display dialog (fruit of f) & "s are " & theColor
		exit repeat
	end if
end repeat

As you see you can use the value of the variable “theColor” to communicate with the fruits inside the record list.
Hope this little hint might help you :slight_smile:

Ciao
Farid

While you can variables for values like normal, you can not use a variable for the “key” (the name of the record element); Any keys/names must be predefined and used in the actual script.

set theFruits to {{fruit:"banana", fruitcolor:"yellow"}, {fruit:"strawberry", fruitcolor:"red"}, {fruit:"apple", fruitcolor:"green"}}

display dialog "Return all values for this key/name:" default answer ""
set theKey to text returned of result

set theList to {}
repeat with thisRecord in theFruits
	set theList's end to theKey of thisRecord
end repeat

return theList

If you try this, you’ll see that the script will try to find a key named theKey.

However, lists are likely an acceptable alternative.

There is a “hack” (and as such not guaranteed to remain viable through upgrades) for computing the element of a record in slightly altered form here from a script by Kai


set MyRecord to {A1:"Banana", A2:"Strawberry", A3:"Apple"}
choose from list {"1 = Yellow", "2 = Red", "3 = Green"}
set myPick to "A" & first character of (result as string)
set myVal to run script (quoted_text for MyRecord) & "'s " & myPick

on quoted_text for v
	try
		{v}'s v
	on error v
		set d to text item delimiters
		set text item delimiters to "{"
		set v to v's text from text item 2 to end
		set text item delimiters to "}"
		set v to v's text beginning thru text item -2
		set text item delimiters to d
		v
	end try
end quoted_text

Or if you were in an AppleScript Studio project (Xcode), you could use NSDictionary’s methods to access an AppleScript record’s keys and objects:

	set theFruits to {fruit:"banana", fruitname:"strawberry", fruittaste:"sweet", fruitcolor:"red"}
	set theKeys to (call method "allKeys" of theFruits) -- -> returns all keys as list: {"fruit", "fruitname", "fruittaste", "fuitcolor"}
	set thisKey to first item of (choose from list theKeys)
	set theObject to (call method "objectForKey:" of theFruits with parameter thisKey) -- -> returns the value for the key you have selected

I prefer to run a script object in a subroutine that evaluates the whole mess on the fly. In the example below, you can re-use it with any list and any key… both identified in variables…

set theRecordList to {qwe:1, rty:2, asd:3, fgh:4}
set theKey to "rty"

return (getRecordValue(theKey, theRecordList)) --> returns: 2

to getRecordValue(theKey, theList)
	run script "on run{theKey,theList}
	return (" & theKey & " of theList )
end" with parameters {theKey, theList}
end getRecordValue

I’ve got this and another simpler example on my hokey little website.

j