7 votos

Emulación de matrices asociativas en AppleScript

Un problema que sería trivial de resolver con pares clave=>valor. Para cada elemento de la lista_a, encontrar el elemento correspondiente en la lista_b y comparar un solo atributo (calcular la relación de escala para dos conjuntos de imágenes).

Las listas de AppleScript son algo así:

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

Ambas listas pueden contener un número diferente de artículos/pedidos, lo que hace imposible la transmisión de nth item of list para la selección de pares

Aunque sería posible iterar sobre cada objeto de la listaA y comparar su propiedad de nombre de archivo con cada objeto de la listaB, esto es terriblemente ineficiente, incluso con sólo unos cientos de elementos.

¿Es posible resolver esto usando AppleScript o debo serializar los objetos y pasar la tarea de evaluación a un script externo que soporte arrays assoc.

4voto

Kaydell Puntos 229

Aunque AppleScript hace tienen matrices asociativas, se llaman "registros". Intenté usar registros de AppleScript para darle una solución. En el código de abajo, no pude usar una cadena como clave. Me las arreglé para usar algo que se parece a un nombre de archivo, un identificador, pero esto no funciona realmente. Sin embargo, es una idea de cómo usar un array asociado en AppleScript:

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

He visto que en tu código de ejemplo, has definido listas de registros. Lo que he intentado hacer es definir registros de registros.

Creo que lo principal que hay que tener en cuenta sobre los puntos fuertes y débiles de AppleScript es que es un lenguaje diseñado para la comunicación entre aplicaciones (IAC), que gira en torno al "comando tell" para decirle a diferentes aplicaciones que obtengan datos, establezcan datos, y para controlar las aplicaciones diciéndoles comandos.

Aquí hay un enlace a una respuesta que creo que es relevante para una solución de AppleScript para usted:

Encontrar la intersección de dos listas

La solución definitiva usando AppleScript sería usar AppleScriptObjC que te permitiría usar clases de Objective-C como NSDictionary que son muy parecidas a las matrices asociativas.

0 votos

Este es un buen ejemplo de cómo intentar esto utilizando AppleScript en bruto, pero para mí, la parte más valiosa de su respuesta es el recordatorio de que AppleScript está pensado para atender a la CAI, por lo que es aceptable (si no se pide) utilizar otra utilidad para una tarea específica, cuando es más adecuada.

0 votos

@remote, estoy de acuerdo. Yo estaba trabajando en otra solución utilizando "puro AppleScript" y un ingeniero de AppleScript de Apple, me aconsejó "shell out" a Perl.

0 votos

Citándome a mí mismo: "Creo que lo principal a tener en cuenta sobre los puntos fuertes y débiles de AppleScript es que es un lenguaje diseñado para la comunicación entre aplicaciones (IAC), que gira en torno al "comando tell". Retiro lo que dije sobre que la falta de arrays asociativos en AppleScript es un defecto del lenguaje ApppleScript, más bien es una deficiencia de la API.

3voto

Si puede utilizar un shell script (o do shell script ), awk soporta matrices asociativas con claves de cadena y búsqueda rápida.

$ 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 Puntos 1

En realidad, es posible que su primer script escriba un segundo script y ejecute el segundo script "dentro del otro", permitiéndole así escribir claves "sobre la marcha". Aquí hay una demostración divertida que juega con el concepto. Espero que te sirva de ayuda.

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

AppleAyuda.com

AppleAyuda es una comunidad de usuarios de los productos de Apple en la que puedes resolver tus problemas y dudas.
Puedes consultar las preguntas de otros usuarios, hacer tus propias preguntas o resolver las de los demás.

Powered by:

X