7 votes

Émulation de tableaux associatifs dans AppleScript

Un problème qui serait trivial à résoudre avec des paires clé=>valeur. Pour chaque élément de la liste_a, trouver l'élément correspondant dans la liste_b et comparer un seul attribut (calculer le rapport d'échelle pour deux ensembles d'images).

Les listes AppleScript ressemblent à ceci :

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"}, ...}

Les deux listes peuvent contenir un nombre différent d'articles/ordre, ce qui rend impossible le relais sur nth item of list pour sélectionner les paires

Il serait possible d'itérer sur chaque objet de la liste A et de comparer sa propriété filename avec chaque objet de la liste B, mais cette méthode est terriblement inefficace, même avec seulement quelques centaines d'éléments.

Est-il possible de résoudre ce problème en utilisant AppleScript ou dois-je sérialiser les objets et passer la tâche d'évaluation à un script externe qui supporte les tableaux d'assoc.

4voto

Kaydell Points 289

Bien qu'AppleScript fait ont des tableaux associatifs, ils sont appelés "records". J'ai essayé d'utiliser les enregistrements AppleScript pour vous donner une solution. Dans le code ci-dessous, je n'ai pas réussi à utiliser une chaîne de caractères comme clé. J'ai réussi à utiliser quelque chose qui ressemble à un nom de fichier, un identifiant, mais cela ne fonctionne pas vraiment. C'est une idée de comment utiliser un tableau d'associés dans AppleScript cependant :

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

J'ai vu que dans votre exemple de code, vous avez défini des listes d'enregistrements. Ce que j'ai essayé de faire, c'est de définir des enregistrements d'enregistrements.

Je pense que la principale chose à garder à l'esprit concernant les forces et les faiblesses d'AppleScript est qu'il s'agit d'un langage conçu pour la communication interapplicative (IAC), qui tourne autour de la "commande tell" pour dire à différentes applications d'obtenir des données, de définir des données, et de contrôler les applications en leur disant des commandes.

Voici un lien vers une réponse qui me semble pertinente pour une solution AppleScript pour vous :

Trouver l'intersection de deux listes

La solution ultime en utilisant AppleScript serait d'utiliser AppleScriptObjC qui vous permettrait d'utiliser des classes Objective-C telles que NSDictionary qui sont très proches des tableaux associatifs.

0 votes

Il s'agit d'un bel exemple de la façon de procéder en utilisant l'AppleScript brut, mais pour moi, la partie la plus précieuse de votre réponse est le rappel que l'AppleScript est conçu pour répondre à la CAI, il est donc acceptable (voire nécessaire) d'utiliser un autre utilitaire pour une tâche spécifique, lorsqu'il est mieux adapté.

0 votes

@remote, je suis d'accord. J'étais en train de travailler sur une autre solution utilisant du "pur AppleScript" et un ingénieur AppleScript d'Apple m'a conseillé de "passer à Perl".

0 votes

Je me cite : "Je pense que la principale chose à garder à l'esprit concernant les forces et les faiblesses d'AppleScript est qu'il s'agit d'un langage conçu pour la communication interapplicative (IAC), qui tourne autour de la "commande tell". Je retire ce que j'ai dit sur le fait que le manque de tableaux associatifs dans AppleScript est un défaut du langage ApppleScript, c'est plutôt une déficience de l'API.

3voto

Si vous pouvez utiliser un shell script (ou do shell script ), awk supporte les tableaux associatifs avec des clés de type chaîne et une recherche rapide.

$ 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

0voto

Mr. Science Points 1

En fait, il est possible pour votre premier script d'écrire un second script et d'exécuter le second script 'à l'intérieur de l'autre', ce qui vous permet d'écrire des clés 'à la volée'. Voici une démo amusante qui joue avec le concept. J'espère que cela vous aidera !

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

LesApples.com

LesApples est une communauté de Apple où vous pouvez résoudre vos problèmes et vos doutes. Vous pouvez consulter les questions des autres utilisateurs d'appareils Apple, poser vos propres questions ou résoudre celles des autres.

Powered by:

X