Emulating associative arrays in AppleScript

A problem that would be trivial to solve with key=>value pairs. For each item in list_a, find the matching item in list_b and compare a single attribute (calculate scale ratio for two sets of images).

The AppleScript lists look something like this:

listA = {{filename:"filename X.tif",width:"500"},{filename:"filename Z.tif",width:"200"}, ...}
listB = {{filename:"filename Z.tif",width:"400"},{filename:"filename v.tif",width:"222"}, ...}

Both lists may contain a different number of items/order, making it impossible to relay on nth item of list for selecting pairs

While it would be possible to iterate over every object in listA and compare its filename property with every object of listB, this is horribly inefficient, even with just a few hundred items.

Is it possible to solve this using AppleScript or must I serialize the objects and pass the evaluation task to an external script that support assoc. arrays?


Although AppleScript does have associative arrays, they are called "records". I tried using AppleScript records to give you a solution. In the code below, I was unable to use a string as a key. I did manage to use something that resembles a file name, an identifier, but this isn't really working. It's an idea of how to use an associate array in AppleScript though:

set theAssociativeArray to {|file name 3.jpg|:{width:400}, |file name 1.jpg|:{width:222}}

-- looking things up by key in an AppleScript record, which is really a dictionary, is fast
try
    get |file name3.jpg| of theAssociativeArray
    say "file name 3 is on list"
on error
    say "file name 3 is not on list"
end try
try
    get |file name 1.jpg| of theAssociativeArray
    say "file name 1 is on list"
on error
    say "file name 1 is not on list"
end try

I saw that in your example code, you defined lists of records. What I tried to do is to define records of records.

I think that the main thing to keep in mind about the strengths and weaknesses of AppleScript is that is a language designed for Interapplication Communication (IAC), revolving a round the "tell command" to tell different apps to get data, set data, and to control the apps by telling them commands.

Here is a link to an answer that I believe is relevant to an AppleScript solution for you:

Finding the Intersection of Two Lists

The ultimate solution using AppleScript would be to use AppleScriptObjC which would allow you to use Objective-C classes such as NSDictionary that are very much like associative arrays.


If you can use a shell script (or do shell script), awk supports associative arrays with string keys and fast lookup.

$ cat widths.txt
2.tif 600
1.tif 500
4.tif 700
$ cat heights.txt
4.tif 1000
2.tif 900
$ awk 'NR==FNR{a[$1]=$2;next}{print $1" "a[$1]/$2}' widths.txt heights.txt
2.tif 0.666667
4.tif 0.7