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
    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
    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.

  • This is a nice example of how to attempt this using raw AppleScript, but to me, the most valuable part of your answer is the reminder that AppleScript is ment to cater for IAC, so it is acceptable (if not called for) to use another utility for a specific task, when it is better suited.
    – cjoy
    Aug 16 '13 at 18:29
  • @remote, I agree. I was working on another solution using "pure AppleScript" and an AppleScript engineer from Apple, advised me to "shell it out" to Perl.
    – Kaydell
    Aug 17 '13 at 1:09
  • Quoting myself: "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". I'm taking back what I said about a lack of associative arrays in AppleScript is a flaw in the ApppleScript language, rather it is a deficiency of the API.
    – Kaydell
    Aug 17 '13 at 1:12

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

Actually, it IS possible for your first script to write a second script and run the second script 'inside the other' thus allowing you to write keys 'on-the-fly'. Here's a fun demo that toys around with the concept. I hope it helps!

--WRITE KEYS TO 'ASOCIATIVE ARRAYS' on theFLY!!!! (a.k.a. applescript 'records') --THIS SCRIPT RANDOMLY GETS A KEY TO EXTRACT A VALUE FROM THE APPLESCRIPT RECORD --THE COOL PART IS THAT IT ALSO GENERATES THE NAME OF THE RECORD --AND THE NAME OF THE LAST KEY IN THE RECORD!!!!!!!!! set USE_ANY_NAME_YOU_LIKE to "double_Oh_7" --try 'MonkeyPenny' or 'Q' or 'double_Oh_7' set RANDUMB_VARIABLE to some item of {"JaymsBond", "secret_Messij", USE_ANY_NAME_YOU_LIKE} set EMBEDEDSCRIPT to " on run(xxx) beep 3 say \"I'm accessing the associative arrays,\" &xxx &\"key.\" return " & RANDUMB_VARIABLE & " of {JaymsBond:007, secret_Messij:\"shaken not stirred\"," & RANDUMB_VARIABLE & ":\"yep\"} end" set z to run script EMBEDEDSCRIPT with parameters {RANDUMB_VARIABLE} return "The value of the " & RANDUMB_VARIABLE & " key is ... " & z

--result 1 >>>"The value of the double_Oh_7 key is ... yep" --result 2 >>>"The value of the JaymsBond key is ... 7" --result 3 >>>"The value of the secret_Messij key is ... shaken not stirred"

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .