Archive for the 'リスト処理(list)' Category
{{”Field1″, “Field2″, “Field3″}, {1,2,3}, {4,5,6}}のような入れ子のリストで、指定フィールド名のデータをキーとしてソートして返すAppleScriptです。
CSVファイルをparseしてリストに変換し、リストに対して指定フィールドの値でソートする場合に使用します。
返り値にはフィールドラベルを含んでいません。ソートルーチンは、中途半端な高速化を行ってあります。最速版のソートルーチンを入れ子のリストに対応させられていなかったので、shell sortの入れ子ルーチンをちょっとだけ高速化した状態です。
| スクリプト名:入れ子のリストから、指定フィールドでソートしてデータを返す |
set aList to {{“ID”, “名称”, “アドレス”, “URL”, “データ”}, {1, 2, 3, 4, 5}, {9, 3, 4, 5, 6}, {3, 4, 5, 6, 7}}
set sortDirecionF to false –true: ascending, false: descending
set resList to getSpecifiedFieldData(aList, “ID”, sortDirecionF) of me –> {{9, 3, 4, 5, 6}, {3, 4, 5, 6, 7}, {1, 2, 3, 4, 5}}
–入れ子のリストから、指定フィールドのデータを取得する –1アイテム目はフィールドラベル。2アイテム目以降をデータと見なして指定フィールドのデータをリストで返す on getSpecifiedFieldData(aData, fieldName, sortAscendF) –与えられたデータaDataの1アイテム目はフィールド名と見なす set fieldList to contents of first item of aData set dataList to contents of items 2 thru -1 of aData set fNum to getNumberOfField(fieldList, fieldName) of me if fNum = 0 then return false if sortAscendF = true then –Ascending set resList to shellSortListAscending(dataList, fNum) of me else –Descending set resList to shellSortListDecending(dataList, fNum) of me end if –フィールドラベルを先頭に付けておく??? –set beginning of dataList to fieldList return resList end getSpecifiedFieldData
–与えられたリスト中における任意テキスト要素の出現アイテム番号 on getNumberOfField(aList, targFieldName) set aCount to 1 repeat with i in aList set j to contents of i if j is equal to targFieldName then return aCount end if set aCount to aCount + 1 end repeat return 0 – no hit end getNumberOfField
–シェルソートで入れ子のリストを昇順ソート on shellSortListAscending(aSortList, keyItem) script oBj property list : aSortList end script set n to count oBj’s list’s items set cols to {1391376, 463792, 198768, 86961, 33936, 13776, 4592, 1968, 861, 336, 112, 48, 21, 7, 3, 1} repeat with h in cols if (h ≤ (n - 1)) then repeat with i from h to (n - 1) set v to item (i + 1) of list of oBj set j to i repeat while (j ≥ h) and ((contents of item keyItem of item (j - h + 1) of list of oBj) > (item keyItem of v)) set (item (j + 1) of list of oBj) to (item (j - h + 1) of list of oBj) set j to j - h end repeat set item (j + 1) of list of oBj to v end repeat end if end repeat return aSortList end shellSortListAscending
–シェルソートで入れ子のリストを降順ソート on shellSortListDecending(aSortList, keyItem) script oBj property list : aSortList end script set n to count oBj’s list’s items set cols to {1391376, 463792, 198768, 86961, 33936, 13776, 4592, 1968, 861, 336, 112, 48, 21, 7, 3, 1} repeat with h in cols if (h ≤ (n - 1)) then repeat with i from h to (n - 1) set v to item (i + 1) of list of oBj set j to i repeat while (j ≥ h) and ((contents of item keyItem of item (j - h + 1) of list of oBj) < (item keyItem of v)) set (item (j + 1) of list of oBj) to (item (j - h + 1) of list of oBj) set j to j - h end repeat set item (j + 1) of list of oBj to v end repeat end if end repeat return aSortList end shellSortListDecending
|
|
▼新規書類に ▼カーソル位置に ▼ドキュメント末尾に
|
Posted in リスト処理(list), 10.5対応, 10.6対応, 10.4対応, 10.7対応, 10.8対応 | No Comments »
{{”Field1″, “Field2″, “Field3″}, {1,2,3}, {4,5,6}}のような入れ子のリストで、指定フィールド名のデータを取得して返すAppleScriptです。
CSVファイルをparseしてリストに変換し、リストに対して指定フィールドの値を抽出する場合に使用します。

オリジナルのデータは、Excel(あるいはNumbersやFileMaker Pro)上で、上図のような状態になっていることを想定しています。1行目がフィールド名ラベルになっているというパターンです(緑色の箇所)。
入れ子のリストの各指定項目を取り出すような場合には、「何アイテム目を取り出す」と記述するケースが多いところですが、アイテム番号を決め打ちでは処理の柔軟性がないので、1アイテム目をフィールドラベルと見なし、そのフィールドラベルで該当する項目番号をサーチして、項目名で指定できるようにしてみました。
AppleScript中心の処理を追求すると、なるべく「テキストエディタやFileMaker Proに依存した処理を行わない」ことが重要になってきます。置換や検索、ソートなどをこれらのアプリケーションに依存していると、いつまでもそのアプリケーションが存在しない環境では自分の処理ができないことになります。
| スクリプト名:入れ子のリストから、指定フィールドのデータを取得する |
set aList to {{"ID", "名称", "アドレス", "URL", "データ"}, {1, 2, 3, 4, 5}, {2, 3, 4, 5, 6}, {3, 4, 5, 6, 7}}
set resList to getSpecifiedFieldData(aList, "名称") of me –> {2, 3, 4}
–入れ子のリストから、指定フィールドのデータを取得する –1アイテム目はフィールドラベル。2アイテム目以降をデータと見なして指定フィールドのデータをリストで返す on getSpecifiedFieldData(aData, fieldName) –与えられたデータaDataの1アイテム目はフィールド名と見なす set fieldList to contents of first item of aData set dataList to contents of items 2 thru -1 of aData set fNum to getNumberOfField(fieldList, fieldName) of me if fNum = 0 then return false set resList to {} repeat with i in dataList set the end of resList to contents of item fNum of i end repeat return resList end getSpecifiedFieldData
–与えられたリスト中における任意テキスト要素の出現アイテム番号 on getNumberOfField(aList, targFieldName) set aCount to 1 repeat with i in aList set j to contents of i if j is equal to targFieldName then return aCount end if set aCount to aCount + 1 end repeat return 0 – no hit end getNumberOfField
|
|
▼新規書類に ▼カーソル位置に ▼ドキュメント末尾に
|
Posted in リスト処理(list), 10.5対応, 10.6対応, 10.4対応, 10.7対応, 10.8対応 | 4 Comments »
{{1,2,3}, {4,5,6}}のような入れ子のリストで、全アイテムのアイテム数が同じかどうかチェックするAppleScriptです。基準となるアイテム数は1アイテム目({1,2,3})を用います。
CSVファイルをparseしてリストに変換し、リストに対して処理を行ってふたたびCSVファイルに書き出すような場合に使用します。合っているとtureを、そうでないとfalseを返します。たいして大きなデータを処理していなかったので、高速化処理などは一切行っていませんが……データの規模によっては高速化処理を行うことがふさわしいところです。
parseした結果としてすべてのアイテムでアイテム数が同じかどうかをチェックすることが目的です。

オリジナルのデータは、Excel(あるいはNumbersやFileMaker Pro)上で、上図のような状態になっていることを想定しています。1行目がフィールド名ラベルになっているというパターンです(緑色の箇所)。
CSVからparseしたリストの項目数が合っていないと、そのあとでさまざまな処理を行おうにも……処理の内容を保証できません。そこで、まずは項目数が合っているかを検証すると安全でしょう。もちろん、フィールド付加などを行ったあとに項目数をカウントしてチェックを行うことも重要です。
ExcelなどからCSVファイルに書き出して、AppleScript側でCSVファイルをもとにデータ処理を行うケースは非常に多いです。AppleScriptの初心者が陥りがちなポイントですが……そのままExcelに対して必要なデータに(行や列を指定して)アクセスすると、当然のことながらデータ数が増えるとものすごく時間がかかります。selectionからデータを取得する例もありますが、selectionから取得できるデータの大きさに上限が存在していたりで、万能とはいえません(とくに、Mac OS X初期に開発されたExcel v.Xあたりはselectionで取得できるデータサイズの上限が小さめです)。
大量のデータ通信をアプリケーションに対して行って、それをもって「AppleScriptの処理が遅い」と判断するのは間違いです。AppleScriptの内部データ表現形式であるリスト型変数やレコードに取り込んで、その上で処理を行うのがセオリーです。
同様の例はテキストエディタのデータを処理する場合などに多々見られ……テキストエディタの編集中のファイルに対して、テキストエディタ経由でアクセスすれば当然のように遅くなります。しかし、「どのファイルを編集中なのか」という情報をテキストエディタから取得して、AppleScriptで自前でテキストファイルにアクセスして処理すれば圧倒的に高速になります。
| スクリプト名:入れ子のリストで、1アイテム目のアイテム数が他と同じかどうかチェック |
set aList to {{“ID”, “名称”, “アドレス”, “URL”, “データ”}, {1, 2, 3, 4, 5}, {2, 3, 4, 5, 6}, {3, 4, 5, 6, 7}}
–リスト中のすべての項目(データ行)のフィールド数が同じかどうかチェック set chRes to chkItemNumInEveryLine(aList) of me –> true
–入れ子のリストで、1アイテム目のアイテム数が他と同じかどうかチェック on chkItemNumInEveryLine(aList) set aList1 to contents of first item of aList set aList2 to contents of items 2 thru -1 of aList set aList1Len to length of aList1 repeat with i in aList2 set tmpLen to length of i if tmpLen is not equal to aList1Len then return false end if end repeat return true end chkItemNumInEveryLine |
|
▼新規書類に ▼カーソル位置に ▼ドキュメント末尾に
|
Posted in リスト処理(list), 10.5対応, 10.6対応, 10.4対応, 10.7対応 | No Comments »
This is a simple AppleScript to find same file name with different extension in same directory.
Sample Data:

Output Data:
–> {{”D120_a.jpg”, “D120_a.png”}, {”D120_c.gif”, “D120_c.jpg”, “D120_c.png”, “D120_c.txt”}}
| スクリプト名:find same file name with different extension in same directory |
–Speed up technic script aRef property aList : {} –every file name of user selected folder ( work) property bList : {} – every file name list (without duplicates) (work) property cList : {} –duplicated file name list (work) property dList : {} –output duplicated file names with different extensions end script
–Initialize variables set aList of aRef to {} set bList of aRef to {} set cList of aRef to {} set dList of aRef to {}
set a to choose folder with prompt "Choose check Folder"
tell application "Finder" tell folder a set aList of aRef to name of every file end tell end tell
–make pure file name list(without extension) to cList repeat with i in aList of aRef set j to contents of i set jj to retFileNameWithoutExt(j) of me if jj is in bList of aRef then –duplicated file name & does not exist in cList if jj is not in cList of aRef then set the end of cList of aRef to jj end if set tmpName to jj & "." tell application "Finder" tell folder a –set dList of aRef to dList of aRef & (name of every file whose name starts with tmpName) set the end of dList of aRef to (name of every file whose name starts with tmpName) end tell end tell end if set the end of bList of aRef to jj end repeat
–Remove duplicates from List set aRes to removeDuplicates(dList of aRef) of me
–> {{"D120_a.jpg", "D120_a.png"}, {"D120_c.gif", "D120_c.jpg", "D120_c.png", "D120_c.txt"}}
–Remove Duplicated Item from List on removeDuplicates(aList) set newList to {} repeat with i from 1 to (length of aList) set anItem to item 1 of aList set aList to rest of aList if {anItem} is not in aList then set end of newList to anItem end repeat return newList end removeDuplicates
–delete extension from file name on retFileNameWithoutExt(fileNameStr) set fLen to length of fileNameStr set revText to (reverse of (characters of fileNameStr)) as string –make reversed string set anOffset to offset of "." in revText set fRes to text 1 thru (fLen - anOffset) of fileNameStr return fRes end retFileNameWithoutExt
|
|
▼新規書類に ▼カーソル位置に ▼ドキュメント末尾に
|
Posted in リスト処理(list), ファイル処理(file), アプリケーション操作(app control), Finder, 10.5対応, 10.6対応, 10.4対応, 10.7対応 | No Comments »
edama2さんよりの投稿です
基本的には掲載されている「シェルソートでリストをソート」をスプリクトオブジェクトで処理にしているだけです。サンプルでソートする数が100倍なだけで「100倍速い」という数字には特に根拠はありません。
| スクリプト名:100倍速いシェルソートでリストをソート |
set theList to {} set i to 1 repeat 30000 times copy (random number from 100 to 99999) to the end of theList set i to i + 1 end repeat
set s0Time to current date set aRes to shellSort_order_(theList, false) of me set s1Time to current date
display dialog (s1Time - s0Time) as string
–シェルソートでリストを昇順ソート(入れ子ではないリスト) on shellSort_order_(a, isAsc) script a_ref property contents : a end script set n to length of a set cols to {1391376, 463792, 198768, 86961, 33936, 13776, 4592, 1968, 861, 336, 112, 48, 21, 7, 3, 1} repeat with h in cols if (h ≤ (n - 1)) then repeat with i from h to (n - 1) set v to item (i + 1) of contents of a_ref set j to i repeat while (j ≥ h) and ((item (j - h + 1) of contents of a_ref) > v) set (item (j + 1) of contents of a_ref) to (item (j - h + 1) of contents of a_ref) set j to j - h end repeat set item (j + 1) of contents of a_ref to v end repeat end if end repeat if not isAsc then set a to a’s reverse return a end shellSort_order_
|
|
▼新規書類に ▼カーソル位置に ▼ドキュメント末尾に
|
Piyomaru Softwareによる解説:
以前に掲載したシェルソートのルーチンの改良版です。ソートというか、巨大なリスト型変数(配列)の操作をAppleScriptで行うとスピードが低下するので、3,000〜4,000要素(Item)を超えるサイズのリスト型変数を扱う場合には、何らかの高速化を行うべきです。
AppleScriptにおけるソートの高速化手法にはおよそ3つあって、1つが「a reference to」による間接アクセスによる高速化。
著しく高速化するものの、データを格納する変数と間接アクセスする変数の2つをグローバル宣言する必要があり、効果は大きいものの、副作用も大きい(グローバル宣言した変数が他のルーチンの変数をぶつかっていないか確認が必要、など)ため、そのための作業コストが大きく「手軽」とはいえませんでした。
2つ目が、ここで活用されている「スクリプトオブジェクト内にプロパティを持つ」というアクセス方法で、a reference toと同程度ぐらいには(厳密に計測してはいないのですが)高速化することが知られています。
スクリプトオブジェクトの利用による高速化処理の前後で、サンプルの3万項目の乱数リストをソート所要時間を計測比較してみたところ(MacBook Pro Core i7 2.66GHz, Mac OS X 10.6.8, 8GB RAM)、
高速化前:2967秒
高速化後:8秒
と、370倍ぐらい高速になっていました。リストの項目が大きいほど高速化の効果が出やすいものと思われます。
3つめが、Mac OS X 10.6から使えるようになったAppleScript ObjCを用いること。この環境内でCocoaのソートルーチンを呼び出すと速いので、一度すべてのやりかたでどのソート方法が速いのか、比較をしておくべきでしょう。
追記(2012/3/4):
MacBook Air 2011 (Core i5 1.6GHz、Mac OS X 10.7.3、RAM 4GB)でこの乱数3万件のソートを試してみたところ……
本ScriptをAppleScript Editor上で実行:7秒
本ScriptをAppleScriptObjC on Xcodeのプロジェクトで実行:8秒
AppleScriptObjC on XcodeのCocoaベースのソートでリスト(正確にはレコード)をScriptのオブジェクトに持たせた場合:129秒
AppleScriptObjC on XcodeのCocoaベースのソートで何も高速化処理を行っていない場合:(計測不能)
Cocoaベースのソートがたいして速くない(純粋にリスト=NSArrayではないので、同じ処理ではないですが)ことに驚きました。AppleScriptObjCのプログラムも、ソート処理をAppleScriptネイティブのものに書き換えておいたほうがよさそうな……。
あるいは、3万件というデータ件数になると、AppleScriptObjCでもCoreDataを併用することを検討すべきなのかもしれません。データベースに入れてしまえば、3万件ごときのソートなど一瞬でしょうし。
さらに追記(2012/3/4):
AppleScriptObjCで以下のようなプログラム(単なるArrayをソート)にしてみたところ、3万件でもソートに要する時間は1秒以下でした(MacBook Pro Core i7 2.66GHz, Mac OS X 10.6.8, RAM 8GB)。
| AppleScriptObjCファイル名:sortArrayAppDelegate.applescript |
– – sortArrayAppDelegate.applescript – sortArray – – Created by Takaaki Naganoya on 12/03/04. – Copyright 2012 Piyomaru Software. All rights reserved. –
script aRef property contents : {} end script
script sortArrayAppDelegate property parent : class “NSObject” on applicationWillFinishLaunching_(aNotification) – Nothing end applicationWillFinishLaunching_ on applicationShouldTerminate_(sender) return current application’s NSTerminateNow end applicationShouldTerminate_ on clicked_(sender) set aList to {} repeat 30000 times tell current application set the end of (contents of aRef) to (random number from 1000 to 9999) as string end tell end repeat tell current application set sTime to current date end tell set theArray to current application’s class “NSMutableArray”’s arrayWithArray_(contents of aRef) set bList to theArray’s sortedArrayUsingSelector_(“localizedCaseInsensitiveCompare:”) tell current application set eTime to current date set totalTime to eTime - sTime end tell display dialog (totalTime as string) end clicked_ end script |
|
▼新規書類に ▼カーソル位置に ▼ドキュメント末尾に
|
Posted in リスト処理(list), 10.5対応, ソート(sorting), 10.6対応, 10.4対応, AppleScriptObjC, 10.7対応, 10.8対応 | No Comments »
「YxX」の形式の文字列を、{Y,X}のように数字のリストにして返すAppleScriptです。
ダイアログから縦横の表のサイズを文字で入力させるインタフェースを作成したときに、そのparse用として作成したものです。たいしたものではありません。
| スクリプト名:「YxX」の形式の文字列を、{Y,X}のように数字のリストにして返す |
set aStr to "3×4" set aRes to divideYxX(aStr) of me –> {3, 4}
–「YxX」の形式の文字列を、{Y,X}のように数字のリストにして返す on divideYxX(aStr) set curDelim to AppleScript’s text item delimiters set AppleScript’s text item delimiters to "x" set tList to every text item of aStr set AppleScript’s text item delimiters to curDelim copy tList to {item1, item2} try set item1 to item1 as integer set item2 to item2 as integer on error return false end try return {item1, item2} end divideYxX |
|
▼新規書類に ▼カーソル位置に ▼ドキュメント末尾に
|
Posted in リスト処理(list), アプリケーション操作(app control), テキスト処理(text), 10.5対応, 10.6対応, 10.4対応, 10.7対応 | No Comments »
リスト項目のシャッフルを行うAppleScriptです。
「リスト項目のシャッフル」という処理自体は、さほど出現頻度の高いものではありません。だいたい、私がいままで作ったことがなかったぐらいなので、この先も作る必要に迫られる可能性は低そうです。
この手の処理は、1項目呼び出すたびにランダム取り出しをするようなケースが多いので、リスト内容をすべて一括でシャッフルするような処理を書くケースは少ないでしょう。
ただ、それでも「ない」とも言い切れないので試しに組んでみました。予想行数は10行ぐらいだったのですが、予想を大幅に超え、書いているうちにトンでもない行数になってしまいました。
当初は投機的にランダムに項目を抽出して、抽出ずみリストに存在する場合には選び直し……という処理を行っていたのですが(→ 投機的処理)、3,000項目ぐらいのリストなら我慢できたものの、5,000項目を超えると遅く感じられました(MacBook Pro 2010 Core i7 2.66GHz+Mac OS X 10.6.8+日常的なアプリケーション立ち上げまくり環境にて検証)。
投機的処理がどのぐらい「無駄な選び直し」を行っているかを調べてみたところ、だいたい与えた項目数の5〜10倍ぐらい無駄な処理を行っていました。この「無駄」がなければ5〜10倍ぐらいは高速に処理できる可能性があったわけです。
そこで、いいかげんに書かないで地道に処理を行ってみたところ、投機的な処理の3倍ぐらいは高速になりました(→ 地道処理)。頻繁にリストの分割/連結を行うので、このあたりのオーバーヘッドが大きそうですが、それでもアイテム数の回数分しかループを回さないので無駄が少なくてすんでいます。


ちなみに、投機的処理を無理矢理「a reference to」による(なげやりな)高速化を施してみたところ、処理時間はずいぶんと改善はしたものの、それでも地道処理に及ばなかったので、地道処理を採用するのがよいのでしょう。


めんどくさかったので、地道処理を高速化させるパターンは試しませんでした。
一般的に、AppleScriptでリスト型変数を使って処理を行う場合には、だいたい5,000項目のデータ数がひとつの目安であり、それを超える場合には高速化処理を真剣に検討する必要があります。つまり、ズボラに組むときには、あまり大量のデータ処理を行わないことが重要、ということです。
| スクリプト名:リスト項目のシャッフル(投機的処理) |
–テスト用に1〜1000までの数字のリストを作成 set aList to {} repeat with i from 1 to 10000 set the end of aList to i end repeat
set t1 to current date set aRes to length of (retShuffledList(aList) of me) set t2 to current date
return (t2 - t1)
on retShuffledList(aList) –出力用リスト set bList to {} set aMax to length of aList set curCount to 0 repeat –ランダム抽出および出力用リスト内の存在確認 set anItem to contents of some item of aList –項目のランダム抽出 if anItem is not in bList then set the end of bList to anItem set curCount to curCount + 1 end if –終了? if curCount = aMax then exit repeat end if end repeat return bList end retShuffledList |
|
▼新規書類に ▼カーソル位置に ▼ドキュメント末尾に
|
| スクリプト名:リスト項目のシャッフル(地道処理) |
–テスト用に1〜1000までの数字のリストを作成 set aList to {} repeat with i from 1 to 10000 set the end of aList to i end repeat
set t1 to current date set aRes to length of (retShuffledList(aList) of me) set t2 to current date
return (t2 - t1)
on retShuffledList(origList) copy origList to aList –出力用リスト set bList to {} set aMax to length of aList repeat aMax times –ランダム抽出および出力用リスト内の存在確認 set curLen to (length of aList) if curLen > 1 then –通常処理 set aRandom to random number from 1 to curLen set anItem to contents of item aRandom of aList set the end of bList to anItem set aList to delListItem(aList, aRandom) of me else –最後の項目の場合の例外処理 set the end of bList to contents of first item of aList end if end repeat return bList end retShuffledList
–リストから指定のアイテムを削除する on delListItem(aList, anItemNo) set newList to {} set aLen to length of aList if anItemNo = 1 then set newList to contents of items 2 thru -1 of aList else if anItemNo = aLen then set newList to contents of items 1 thru -2 of aList else set p1List to contents of items 1 thru (anItemNo - 1) of aList set p2List to contents of items (anItemNo + 1) thru -1 of aList set newList to p1List & p2List end if return newList end delListItem
|
|
▼新規書類に ▼カーソル位置に ▼ドキュメント末尾に
|
| スクリプト名:リスト項目のシャッフル(投機的処理) +高速化 |
global aList, aList_r global aaaList, aaaList_r global bList, bList_r
–テスト用に1〜1000までの数字のリストを作成 set aList to {} set aList_r to a reference to aList
repeat with i from 1 to 10000 set the end of aList_r to i end repeat
set t1 to current date set aRes to length of (retShuffledList(aList_r) of me) set t2 to current date
return (t2 - t1)
on retShuffledList(aaList) copy aaList to aaaList set aaaList_r to a reference to aaaList –出力用リスト set bList to {} set bList_r to a reference to bList set aMax to length of aaaList_r set curCount to 0 repeat –ランダム抽出および出力用リスト内の存在確認 set anItem to contents of some item of aaaList_r –項目のランダム抽出 if anItem is not in bList_r then set the end of bList_r to anItem set curCount to curCount + 1 end if –終了? if curCount = aMax then exit repeat end if end repeat return bList end retShuffledList |
|
▼新規書類に ▼カーソル位置に ▼ドキュメント末尾に
|
Posted in リスト処理(list), 10.5対応, 10.6対応, 10.4対応, 10.7対応 | No Comments »
指定リストから指定番号のアイテムを削除するAppleScriptです。
ここで言う「指定番号」とは、アイテム番号のことです。
書き捨てレベルのものなので、よく書いてしまうのですが……何らかの巨大なAppleScriptの必須部品として利用するものの、それ自体をsaveするほどでもないので本Blogに掲載していなかったという……。
| スクリプト名:リストから指定のアイテムを削除する(1項目) |
set aList to {1, 2, 3, 4, 5} set bList to delListItem(aList, 4) of me –> {1, 2, 3, 5}
–リストから指定のアイテムを削除する on delListItem(aList, anItemNo) set newList to {} set aLen to length of aList if anItemNo = 1 then set newList to contents of items 2 thru -1 of aList else if anItemNo = aLen then set newList to contents of items 1 thru -2 of aList else set p1List to contents of items 1 thru (anItemNo - 1) of aList set p2List to contents of items (anItemNo + 1) thru -1 of aList set newList to p1List & p2List end if return newList end delListItem |
|
▼新規書類に ▼カーソル位置に ▼ドキュメント末尾に
|
Posted in リスト処理(list), 10.5対応, 10.6対応, 10.4対応, 10.7対応 | No Comments »
true/falseの入ったリストを処理して、falseが入っていたアイテム番号をリストで返すAppleScriptです。
| スクリプト名:与えられたリスト中のfalseの項目番号をリストで返す |
set aaList to {true, true, true, false, true, false} set aRes to retFalseItemNoFromList(aaList) of me –> {4, 6}
–与えられたリスト中のfalseの項目番号をリストで返す on retFalseItemNoFromList(aList) set aCount to 1 set eResList to {} repeat with i in aList set j to contents of i if j is not equal to true then set the end of eResList to aCount end if set aCount to aCount + 1 end repeat return eResList end retFalseItemNoFromList |
|
▼新規書類に ▼カーソル位置に ▼ドキュメント末尾に
|
Posted in リスト処理(list), 10.5対応, 10.6対応, 10.4対応, 10.7対応 | No Comments »
文字列中に指定文字が何個入っているかカウントし、出現数と出現位置のリストを返すAppleScriptです。
| スクリプト名:文字列中に指定文字が何個入っているかカウントする v2 |
set a to “Joe A Hisaishi” set aTargChar to ” “
set bList to countAcharInStrAndDetectPos(a, aTargChar) of me –> {2, {4, 6}} –指定文字の出現回数カウント、登場位置リスト
–文字列中に指定文字が何個入っているかカウントし、登場位置をリストで返す on countAcharInStrAndDetectPos(aStr, aTargChar) set aList to {} set posC to 1 considering case set aHit to offset of aTargChar in aStr if aHit is not equal to 0 then set aaList to characters of aStr set aCount to 0 repeat with i in aaList set j to contents of i if j = aTargChar then set aCount to aCount + 1 set the end of aList to posC end if set posC to posC + 1 end repeat return {aCount, aList} else return {0, {}} end if end considering end countAcharInStrAndDetectPos |
|
▼新規書類に ▼カーソル位置に ▼ドキュメント末尾に
|
Posted in リスト処理(list), テキスト処理(text), 10.5対応, 10.6対応, 10.4対応, 10.7対応 | No Comments »
リスト同士の引き算、足し算を行うAppleScriptです。
リストの要素数が同じことが前提条件です。
要素数が多いリストの演算だとOSAXを併用することも考えたいところですが、それほど多くないものであれば、けっこうこんな簡単なルーチンを用意して処理させても大丈夫です。
| スクリプト名:リスト同士の引き算、足し算 |
set aList to {15.07, 9.275, 18.63, 19.45} set bList to {15.381, 11.6, 18.601, 15.7}
set aRes to listSubstraction(aList, bList) of me –> {-0.311, -2.325, 0.029, 3.75}
–リスト同士の引き算 on listSubstraction(aList, bList) –アイテム数をくらべて、合っていなければエラー set aLen to length of aList set bLen to length of bList if aLen is not equal to bLen then return {} set aResList to {} repeat with i from 1 to aLen set itemA to contents of item i of aList set itemB to contents of item i of bList set tmpR to itemA - itemB set the end of aResList to tmpR end repeat return aResList end listSubstraction
–リスト同士の足し算 on listAddition(aList, bList) –アイテム数をくらべて、合っていなければエラー set aLen to length of aList set bLen to length of bList if aLen is not equal to bLen then return {} set aResList to {} repeat with i from 1 to aLen set itemA to contents of item i of aList set itemB to contents of item i of bList set tmpR to itemA + itemB set the end of aResList to tmpR end repeat return aResList end listAddition
|
|
▼新規書類に ▼カーソル位置に ▼ドキュメント末尾に
|
Posted in リスト処理(list), 10.5対応, 10.6対応, 10.4対応, 10.7対応 | No Comments »
InDesign CS3で選択中のオブジェクトの外周部の座標を取得するAppleScriptです。

複数のオブジェクトの外周部の座標のみ取得したいという場合、安直にグループ化してその座標(geometric bouds)を取得する方法も考えないではないですが、元に戻すときに何かよくないこと(前後関係が狂うとか)が起こる可能性があるため、「グループ化→座標取得→グループ化解除」の順で処理するのは避けたいところ。
そこで、力ワザでありもののソートルーチンを用いて、ソートだけで取得するように処理してみました。y1とx1は昇順ソート、y2とx2は降順ソートして、それぞれ最初の項目から値を取得しています。
基礎的な属性アクセスしか使っていないため、とくにInDesignのバージョンに依存せずに使用できるはずです(tellブロックのアプリケーション名を書き換えるぐらい)。
| スクリプト名:InDesign CS3で選択中のオブジェクトの外周部の座標を取得する |
tell application “Adobe InDesign CS3″ tell active document set gList to geometric bounds of selection copy gList to y1List copy gList to y2List copy gList to x1List copy gList to x2List set y1Res to shellSortListAscending(y1List, 1) of me set x1Res to shellSortListAscending(x1List, 2) of me set y2Res to shellSortListDecending(y2List, 3) of me set x2Res to shellSortListDecending(x2List, 4) of me –外周部の座標を取得する –y1, x1は最小のものを取得 set y1min to item 1 of item 1 of y1Res set x1min to item 2 of item 1 of x1Res –y2, x2は最大のものを取得 set y2max to item 3 of item 1 of y2Res set x2max to item 4 of item 1 of x2Res return {y1min, x1min, y2max, x2max} –> {64.666666666667, 39.0, 177.0, 202.0} end tell end tell
–シェルソートで入れ子のリストを昇順ソート on shellSortListAscending(a, keyItem) set n to length of a set cols to {1391376, 463792, 198768, 86961, 33936, 13776, 4592, 1968, 861, 336, 112, 48, 21, 7, 3, 1} repeat with h in cols if (h ≤ (n - 1)) then repeat with i from h to (n - 1) set v to item (i + 1) of a set j to i repeat while (j ≥ h) and ((contents of item keyItem of item (j - h + 1) of a) > (item keyItem of v)) set (item (j + 1) of a) to (item (j - h + 1) of a) set j to j - h end repeat set item (j + 1) of a to v end repeat end if end repeat return a end shellSortListAscending
–シェルソートで入れ子のリストを降順ソート on shellSortListDecending(a, keyItem) set n to length of a set cols to {1391376, 463792, 198768, 86961, 33936, 13776, 4592, 1968, 861, 336, 112, 48, 21, 7, 3, 1} repeat with h in cols if (h ≤ (n - 1)) then repeat with i from h to (n - 1) set v to item (i + 1) of a set j to i repeat while (j ≥ h) and ((contents of item keyItem of item (j - h + 1) of a) < (item keyItem of v)) set (item (j + 1) of a) to (item (j - h + 1) of a) set j to j - h end repeat set item (j + 1) of a to v end repeat end if end repeat return a end shellSortListDecending
|
|
▼新規書類に ▼カーソル位置に ▼ドキュメント末尾に
|
Posted in リスト処理(list), アプリケーション操作(app control), 10.5対応, 10.6対応, InDesign CS3, 10.4対応 | No Comments »
指定矩形内に含まれるデータをアイテム番号で返すAppleScriptです。
以前に、指定矩形座標内に含まれる座標をピックアップというAppleScriptを掲載しましたが、その時にはデータ内容そのもの(contents)を返していました。InDesignの座標系である{Y1,X1,Y2,X2} という(珍妙な)座標の並び順を想定しています。
本ルーチンでは、アイテム番号を返すように一部変更したものです。
別途、オブジェクト参照のリストを保持しておき、本ルーチンで座標値の判定を行ったのちに、オブジェクト参照リストから対象をピックアップするような処理を想定しています。
| スクリプト名:指定矩形内に含まれるデータをアイテム番号で返す |
set aList to {{243.0, 17.0, 245.0, 77.0}, {169.000015228534, 12.0, 187.500015228534, 166.999999999992}, {189.000007614311, 13.0, 242.000007614312, 17.0}, {188.999990448174, 17.0, 241.999990448174, 76.999999025133}, {188.999990448174, 87.5, 241.999990448174, 123.5}}
set rangeList to {236.999990448174, 12.0, 246.999990448174, 81.999999025133} –{y1,x1,y2,x2} set resList to withinRange_Y1X1Y2X2_retByID(rangeList, aList) of me
–指定矩形内に含まれるデータをアイテム番号で返す on withinRange_Y1X1Y2X2_retByID(rangeList, targetList) set includedList to {} set aCount to 1 set y1 to item 1 of rangeList set x1 to item 2 of rangeList set y2 to item 3 of rangeList set x2 to item 4 of rangeList repeat with i in targetList set targY1 to item 1 of i set targX1 to item 2 of i set targY2 to item 3 of i set targX2 to item 4 of i if (x1 < targX1) and (x2 > targX2) and (y1 < targY1) and (y2 > targY2) then set the end of includedList to aCount end if set aCount to aCount + 1 end repeat return includedList end withinRange_Y1X1Y2X2_retByID
|
|
▼新規書類に ▼カーソル位置に ▼ドキュメント末尾に
|
Posted in リスト処理(list), 10.5対応, 10.6対応, 10.4対応 | No Comments »
与えられたリストのうち、指定アイテム以降は指定アイテム目に改行で区切って連結するAppleScriptです。
たとえば、要素数が7つあるリストのうち、4アイテム目以降をこの処理対象と指定した場合、4〜7アイテム目が(改行をはさんて)連結されます。
| スクリプト名:指定アイテム以降は指定アイテム目に改行で区切って連結する |
set aList to {"○○初等部", "○○中等部", "○○高等部(400)", "○○大学", "○○女子短期大学", "○○女子短期大学"}
set a to mergeLastItem(aList, 4) of me –> (* {"○○初等部", "○○中等部", "○○高等部(400)", "○○大学 ○○女子短期大学 ○○女子短期大学"}
*)
–指定アイテム以降は指定アイテム目に改行で区切って連結する on mergeLastItem(aList, aLimit) set aLen to length of aList if aLen > aLimit then set newItem to "" set tmpList to items aLimit thru aLen of aList set newItem to retDelimedText(tmpList, return) of me set bList to items 1 thru (aLimit - 1) of aList set the end of bList to newItem set aList to bList end if return aList end mergeLastItem
on retDelimedText(aList, aDelim) set aText to "" set curDelim to AppleScript’s text item delimiters set AppleScript’s text item delimiters to aDelim set aText to aList as text set AppleScript’s text item delimiters to curDelim return aText end retDelimedText
|
|
▼新規書類に ▼カーソル位置に ▼ドキュメント末尾に
|
Posted in リスト処理(list), テキスト処理(text), 10.5対応, 10.6対応, 10.4対応 | No Comments »
リスト中の値が連続する箇所をアイテム番号のリストで返すAppleScriptの修正版です。
実際にほかのルーチンと組み合わせてみたら間違いが判明したので修正しました。
さきほどの、
{”プロジェクト階層図”, “ストレージ仕様”, “データ仕様”, “年間仕様”, “年間仕様”, “年間仕様”, “YP仕様”, “YP仕様”, “YP仕様”, “月間仕様”, “月間仕様”, “月間仕様”, “月間仕様”, “月間仕様”, “月間仕様”, “月間仕様”, “月間仕様”}
というデータを処理した場合に、先ほどは……
{{4, 6}, {8, 9}, {11, 17}}
という結果が返ってきていましたが、本当は……
{{4, 6}, {7, 9}, {10, 17}}
が返ってこなくてはならなかったのでした。連続部分の末尾を見つけた直後の動作が一部おかしかったので、そこだけ修正しました。
| スクリプト名:リスト中の値が連続する箇所をアイテム番号のリストで返す v2 |
set aList to {"プロジェクト階層図", "ストレージ仕様", "データ仕様", "年間仕様", "年間仕様", "年間仕様", "YP仕様", "YP仕様", "YP仕様", "月間仕様", "月間仕様", "月間仕様", "月間仕様", "月間仕様", "月間仕様", "月間仕様", "月間仕様"}
set sList to detectRepetition(aList) of me
sList –> {{4, 6}, {7, 9}, {10, 17}}
–リスト中の値が連続する箇所をアイテム番号のリストで返す on detectRepetition(aList) set curItem to first item of aList set aList to rest of aList set aCount to 1 set sucF to false set sList to {} set curList to {} repeat with i in aList set j to contents of i if curItem is equal to j then if sucF = true then –何もしない。データの連続部分の中をスキャン中 else set curItem to j set curList to {aCount} set sucF to true end if else if sucF = true then –連続部分の末尾を見つけた set the end of curList to aCount set the end of sList to curList set curList to {} set curItem to j –ここを修正した set sucF to false else –なにもしない set curItem to j end if end if set aCount to aCount + 1 end repeat if sucF = true then set the end of curList to aCount set the end of sList to curList end if return sList end detectRepetition |
|
▼新規書類に ▼カーソル位置に ▼ドキュメント末尾に
|
Posted in リスト処理(list) | No Comments »
リスト中の値が連続する箇所をアイテム番号のリストで返すAppleScriptです。
{”プロジェクト階層図”, ”ストレージ仕様”, ”データ仕様”, ”年間仕様”, ”年間仕様”, ”年間仕様”, ”YPLAN仕様”, ”YPLAN仕様”, ”YPLAN仕様”, ”月間仕様”, ”月間仕様”, ”月間仕様”, ”月間仕様”, ”月間仕様”, ”月間仕様”, ”月間仕様”, ”月間仕様”}
というリストがあった場合に、本Scriptを実行すると、
{{4, 6}, {8, 9}, {11, 17}}
という結果が得られます。これは、4〜6アイテム目、8〜9アイテム目そして11〜17アイテム目が同一内容が連続していることを示しています。
Keynoteで仕様書を作っていたら、どんどん内容が増えてしまい、
「どこかの部分の仕様(1/3)」
などと書いておいたものが、あとからあとから「(1/3)」の部分が変更になって、なんでこんなものを人の手で更新しなければならないのだとイライラが最高潮に。
おもむろにAppleScriptエディタを立ち上げ、AppleScriptでしばらくKeynoteをこづき回していたところ、各slideのtitleの取得および設定ができることを確認。
ふだん、Keynoteで書類を作る場合にはKeynoteが用意している「マスタースライド」の機能は完全に無視して、「空白」のマスタースライドの上に好き勝手にアイテムを配置していたのですが……あえてマスタースライドの機能を利用すると、きちんとslideのtitle属性部分に各ページのタイトルが入ることを確認。
「じゃあ、AppleScriptでKeynoteのスライドのタイトルを取得して連続部分のリナンバーをさせればよいのではないか?」
と、思い立ち……アイデアだけメモっておいて実際に作りはじめてみた次第です。
本ルーチンはその処理を実現するためのキーとなるものであり、もう少し組めば実現でき……るのではないでしょうか?
| スクリプト名:リスト中の値が連続する箇所をアイテム番号のリストで返す |
set aList to {“プロジェクト階層図”, “ストレージ仕様”, “データ仕様”, “年間仕様”, “年間仕様”, “年間仕様”, “YPLAN仕様”, “YPLAN仕様”, “YPLAN仕様”, “月間仕様”, “月間仕様”, “月間仕様”, “月間仕様”, “月間仕様”, “月間仕様”, “月間仕様”, “月間仕様”}
set sList to detectRepetition(aList) of me
sList –> {{4, 6}, {8, 9}, {11, 17}}
–リスト中の値が連続する箇所をアイテム番号のリストで返す on detectRepetition(aList) set curItem to first item of aList set aList to rest of aList set aCount to 1 set sucF to false set sList to {} set curList to {} repeat with i in aList set j to contents of i if curItem is equal to j then if sucF = true then –何もしない。データの連続部分の中をスキャン中 else set curItem to j set curList to {aCount} set sucF to true end if else if sucF = true then –連続部分の末尾を見つけた set the end of curList to aCount set the end of sList to curList set curList to {} set curItem to “” set sucF to false else –なにもしない set curItem to j end if end if set aCount to aCount + 1 end repeat if sucF = true then set the end of curList to aCount set the end of sList to curList end if return sList end detectRepetition |
|
▼新規書類に ▼カーソル位置に ▼ドキュメント末尾に
|
Posted in リスト処理(list), 10.5対応, 10.6対応 | No Comments »
与えられたリストを連続部分に分解するAppleScriptです。本ルーチンは、連続状態を与えられたリストのデータで返します。
リスト中に「n文字目」といった情報が入っている場合には、アイテム番号を返されるよりはデータ内容を返したほうが有用です。実際に必要に迫られて作成した次第。
| スクリプト名:数値リストを連続部分に分解する(データを返す) |
set aList to {30, 40, 41, 42, 43, 44, 45, 46, 47, 48, 63, 64, 85, 86, 88, 89, 90, 107, 108, 109, 110, 111, 112, 113, 114, 115}
set aRes to splitListByBreakAndReturnContentList(aList) of me –> {{30, 30}, {40, 48}, {63, 64}, {85, 86}, {88, 90}, {107, 115}}
–数値リストを連続部分に分解する(データを返す) on splitListByBreakAndReturnContentList(aList) set bList to detectChangeInNumSeriesList(aList) of me –return bList –> {9, 11, 13, 16}–アイテムの切れ目を検出する if length of bList is not equal to 1 then set prevItem to contents of first item of bList set bList to rest of bList set outList to {{first item of aList, item prevItem of aList}} repeat with i in bList set j1 to prevItem + 1 set j2 to contents of i set the end of outList to {item j1 of aList, item j2 of aList} set prevItem to j2 end repeat set aLen to length of aList if j2 is not equal to aLen then set the end of outList to {item (j2 + 1) of aList, item aLen of aList} end if else set outList to {item (contents of first item of bList) of aList} end if return outList end splitListByBreakAndReturnContentList
on detectChangeInNumSeriesList(aNumList) set prevNum to (first item of aNumList) set bNumList to rest of aNumList set outList to {} set iCount to 1 repeat with i in bNumList set j to contents of i if prevNum = (j - 1) then – else set the end of outList to iCount end if copy j to prevNum set iCount to iCount + 1 end repeat –すべて連続していた場合への対処 if outList = {} then set outList to {{1, length of aNumList}} end if return outList end detectChangeInNumSeriesList
|
|
▼新規書類に ▼カーソル位置に ▼ドキュメント末尾に
|
Posted in リスト処理(list), 10.5対応, 10.6対応, 10.4対応 | No Comments »
与えられたリストを連続部分に分解するAppleScriptです。本ルーチンは、連続状態を与えられたリストのアイテム番号で返します。
AppleScriptによる高速処理、とくにアプリケーションのコントロールの高速化を考えたときに、たとえばあるオブジェクト中の文字の書式を変更するという処理。頭から1文字ずつ処理するよりも、「○文字目から○文字目までの書式を変更しろ」と指定したほうが、はるかに速く処理できます。
アイテム番号で結果を返す本ルーチンは、そうした高速処理に絶大な威力を発揮します。
| スクリプト名:数値リストを連続部分に分解する(アイテム番号を返す) |
set aList to {40, 41, 42, 43, 44, 45, 46, 47, 48, 63, 64, 85, 86, 88, 89, 90, 107, 108, 109, 110, 111, 112, 113, 114, 115}
set aRes to splitListByBreakAndReturnItemNumList(aList) of me –> {{1, 9}, {10, 11}, {12, 13}, {14, 16}, {17, 25}}
–数値リストを連続部分に分解する(アイテム番号を返す) on splitListByBreakAndReturnItemNumList(aList) set bList to detectChangeInNumSeriesList(aList) of me if length of bList is not equal to 1 then set prevItem to contents of first item of bList set bList to rest of bList set outList to {{1, prevItem}} repeat with i in bList set j1 to prevItem + 1 set j2 to contents of i set the end of outList to {j1, j2} set prevItem to j2 end repeat set aLen to length of aList if j2 is not equal to aLen then set the end of outList to {j2 + 1, aLen} end if else set outList to {contents of first item of bList} end if return outList end splitListByBreakAndReturnItemNumList
on detectChangeInNumSeriesList(aNumList) set prevNum to (first item of aNumList) set bNumList to rest of aNumList set outList to {} set iCount to 1 repeat with i in bNumList set j to contents of i if prevNum = (j - 1) then – else set the end of outList to iCount end if copy j to prevNum set iCount to iCount + 1 end repeat –すべて連続していた場合への対処 if outList = {} then set outList to {{1, length of aNumList}} end if return outList end detectChangeInNumSeriesList |
|
▼新規書類に ▼カーソル位置に ▼ドキュメント末尾に
|
Posted in リスト処理(list), アプリケーション操作(app control), 10.5対応, 10.6対応, 10.4対応 | No Comments »
入れ子のリストをタブ区切りのテキストに変換するAppleScriptです。
分布リスト作成v1で作成したデータをテキスト化するために、さくっと作ってみましたが……同じものを以前に何度か作ったような……。
| スクリプト名:入れ子のリストをタブ区切りのテキストに |
set aList to {{"on handler1(thisYear, m)", "●", "●"}, {"on handler2(writeOutPathStr)", "●", ""}, {"on handler3(templatePath)", "●", ""}, {"on handler4(lastCellAdrNum)", "●", ""}, {"on handler5(aList, namePrefix, layerName)", "●", ""}, {"on handler2(aList, aDelim)", "", "●"}, {"on handler3(aList)", "", "●"}, {"on handler7(targetFrameName)", "", "●"}, {"on handler8(aStr)", "", "●"}}
set aText to retItemDelimedAndParagraphDelimedText(aList, tab, return) of me –> (* "on handler1(thisYear, m) ● ● on handler2(writeOutPathStr) ● on handler3(templatePath) ● on handler4(lastCellAdrNum) ● on handler5(aList, namePrefix, layerName) ● on handler2(aList, aDelim) ● on handler3(aList) ● on handler7(targetFrameName) ● on handler8(aStr) ● " *)
–入れ子のリストを、アイテム間のデリミタとパラグラフ間のデリミタを指定してテキスト化 –というか、入れ子のリストをタブ区切りテキストにするのが目的 on retItemDelimedAndParagraphDelimedText(aList, itemDelim, paragraphDelim) set aText to "" repeat with i in aList set aStr to retDelimedText(i, itemDelim) of me set aText to aText & aStr & paragraphDelim end repeat return aText end retItemDelimedAndParagraphDelimedText
on retDelimedText(aList, aDelim) set aText to "" set curDelim to AppleScript’s text item delimiters set AppleScript’s text item delimiters to aDelim set aText to aList as text set AppleScript’s text item delimiters to curDelim return aText end retDelimedText
|
|
▼新規書類に ▼カーソル位置に ▼ドキュメント末尾に
|
Posted in リスト処理(list), テキスト処理(text), 10.5対応, 10.6対応, 10.4対応 | No Comments »
2つのAppleScriptプログラム内の使用ハンドラ一覧の分布リストを作成するAppleScriptです。AppleScriptのプログラム解析用のAppleScriptです。
構成が似通ったプログラムを大量に作ったときに、使用サブルーチンの差異を一覧表にまとめるべく作成しました。
資料を作成するために手作業で集計を行っていたのですが、あまりに面倒なのでプログラムで片づけることにしてみました。
このバージョンでは、2つのAppleScriptのハンドラ同士を比較していますが、実際には8つぐらいのAppleScriptのサブルーチン分布リストを作成。ハンドラの抽出については、別途AppleScriptのプログラムで行っておきましたが……そこまですべて通しで全自動で比較表を作ってみるようにしてもよいかもしれません。
冷静に評価してみると、このプログラム……けっこう応用範囲が広そうです。
| スクリプト名:分布リスト作成 v1 |
–ハンドラ対照表を作成する
property trueChar : “●” property falseChar : “”
set h1List to getH1() of me set h2List to getH2() of me
–元になるアイテムリストを作成する set newList to {} repeat with i in h1List set aLine to {contents of i, trueChar} set the end of newList to aLine end repeat
set aRes to makeDiffTable(newList, h2List, 1) of me –> {{”on handler1(thisYear, m)”, “●”, “●”}, {”on handler2(writeOutPathStr)”, “●”, “”}, {”on handler3(templatePath)”, “●”, “”}, {”on handler4(lastCellAdrNum)”, “●”, “”}, {”on handler5(aList, namePrefix, layerName)”, “●”, “”}, {”on handler2(aList, aDelim)”, “”, “●”}, {”on handler3(aList)”, “”, “●”}, {”on handler7(targetFrameName)”, “”, “●”}, {”on handler8(aStr)”, “”, “●”}}
on makeDiffTable(newList, h2List, blankCount) set aLen to length of h2List set aaLen to length of newList repeat with i from 1 to aLen –ハンドラを取り出す set aCon to contents of item i of h2List set hitF to false repeat with ii from 1 to aaLen set bCon to (first item of (item ii of newList)) if bCon = aCon then set the end of (item ii of newList) to trueChar set hitF to true –exit repeat end if end repeat if hitF = false then set newItem to {aCon} repeat blankCount times set the end of newItem to falseChar end repeat set the end of newItem to trueChar set the end of newList to newItem end if end repeat –newListのアイテム数が合わない箇所にブランクを足す set maxItemNum to retMaxListNumber(newList) of me set newList to setBlankToEndToShorterItem(newList, maxItemNum, “”) of me –ブランク要素として”_”を指定する return newList end makeDiffTable
–与えられたリストのうち、最大長に足りないアイテムに対し、blankItemを追加する on setBlankToEndToShorterItem(aList, maxItemNum, blankItem) set newList to {} repeat with i in aList set j to contents of i set aLen to length of j if aLen is not equal to maxItemNum then set loopNum to maxItemNum - aLen repeat with ii from 1 to loopNum set the end of j to blankItem end repeat end if set the end of newList to j end repeat return newList end setBlankToEndToShorterItem
–リスト中のすべてのアイテムをループして、アイテム数の最大のものを求める on retMaxListNumber(aList) set maxNum to 0 repeat with i in aList set aLen to length of i if maxNum < aLen then set maxNum to aLen end if end repeat return maxNum end retMaxListNumber
on getH1() return paragraphs of “on handler1(thisYear, m) on handler2(writeOutPathStr) on handler3(templatePath) on handler4(lastCellAdrNum) on handler5(aList, namePrefix, layerName)” end getH1
on getH2() return paragraphs of “on handler1(thisYear, m) on handler2(aList, aDelim) on handler3(aList) on handler7(targetFrameName) on handler8(aStr)” end getH2
|
|
▼新規書類に ▼カーソル位置に ▼ドキュメント末尾に
|
Posted in リスト処理(list), 10.5対応, 10.6対応, 10.4対応 | No Comments »
与えられたaliasのリストを各ファイルの作成日でソートして古い順に返すAppleScriptです。
ドラッグ&ドロップすると指定のプリンタにInDesignから印刷を行うAppleScriptのドロップレットを書いて使ってみたら、プリンタに送られる順番が目茶苦茶になってしまいました。
あとから印刷結果を手でソートすることほどむなしいことはありません。
そこで、ドロップレット用にファイルの作成日時でソートするサブルーチンを、汎用ルーチンの寄せ集めで作った次第です。

こんな風にFinder上でファイルを選択しておいて本Scriptを実行すると、作成日時が古い順にソートして返してくれます。AppleScriptから数百ファイルもドキュメントを生成して、印刷しなければならないような場合でも、作成日時の古い順から印刷してくれます。
のんびりしていそうな割には、切実なニーズを満たすために作成したものだったりします。
| スクリプト名:aliasのリストをファイルの作成日でソートして返す |
tell application "Finder" set aSel to selection as alias list end tell
–ファイル作成日でソート(古いものから新しいものへ) set aliasRes to sortAliasByCreationDate(aSel) of me
–> {alias "Cherry:Users:maro:Documents:AppleScript:MacJournalで選択中のjournal entryのBlog公開ステータスを取得する.scpt", alias "Cherry:Users:maro:Documents:AppleScript:目に見えるプロセス一覧を取得する.scpt", alias "Cherry:Users:maro:Documents:AppleScript:最前面のアプリケーションを取得する.scpt", alias "Cherry:Users:maro:Documents:AppleScript:InDesignの文字置換機能を用いた文字置換.scpt", alias "Cherry:Users:maro:Documents:AppleScript:aliasのリストをファイルの作成日でソートして返す.scpt"}
on sortAliasByCreationDate(aliasList) tell application "Finder" set aList to {} repeat with i in aliasList set j to contents of i set the end of aList to {j, creation date of j} end repeat set cList to shellSortListAscending(aList, 2) of me –で作成日時でソート set aliasList to {} set fnCount to 1 repeat with i in cList set j to contents of (item 1 of i) set the end of aliasList to j end repeat end tell return aliasList end sortAliasByCreationDate
–シェルソートで入れ子のリストを昇順ソート on shellSortListAscending(a, keyItem) set n to length of a set cols to {1391376, 463792, 198768, 86961, 33936, 13776, 4592, 1968, 861, 336, 112, 48, 21, 7, 3, 1} repeat with h in cols if (h ≤ (n - 1)) then repeat with i from h to (n - 1) set v to item (i + 1) of a set j to i repeat while (j ≥ h) and ((contents of item keyItem of item (j - h + 1) of a) > (item keyItem of v)) set (item (j + 1) of a) to (item (j - h + 1) of a) set j to j - h end repeat set item (j + 1) of a to v end repeat end if end repeat return a end shellSortListAscending
–シェルソートで入れ子のリストを降順ソート on shellSortListDecending(a, keyItem) set n to length of a set cols to {1391376, 463792, 198768, 86961, 33936, 13776, 4592, 1968, 861, 336, 112, 48, 21, 7, 3, 1} repeat with h in cols if (h ≤ (n - 1)) then repeat with i from h to (n - 1) set v to item (i + 1) of a set j to i repeat while (j ≥ h) and ((contents of item keyItem of item (j - h + 1) of a) < (item keyItem of v)) set (item (j + 1) of a) to (item (j - h + 1) of a) set j to j - h end repeat set item (j + 1) of a to v end repeat end if end repeat return a end shellSortListDecending
|
|
▼新規書類に ▼カーソル位置に ▼ドキュメント末尾に
|
Posted in リスト処理(list), ファイル処理(file), アプリケーション操作(app control), Finder, 10.5対応, 10.6対応, 10.4対応 | No Comments »
指定年のすべての日付をdateオブジェクトで取得するAppleScriptです。
こういう基礎的なプログラムは、誰が組んでもあんまり差が出ないので、あえてゼロから組む必要性がなく……こうした基礎的な部品を組み合わせてどれだけ高度な処理を組み上げられるか、というところに頭を使いたいところです。
| スクリプト名:指定年のすべての日付をdateオブジェクトで取得する |
set thisYear to 2020 set dList to {}
repeat with i from 1 to 12 set mLen to getMlen(thisYear, i) of me repeat with ii from 1 to mLen set dStr to (thisYear as string) & "/" & (i as string) & "/" & (ii as string) set the end of dList to date dStr end repeat end repeat
dList
–指定月の長さを得る(日数) on getMlen(aYear, aMonth) set aDat to (aYear as text) & "/" & (aMonth as text) & "/1" if aMonth is not equal to 12 then set eDat to ((aYear as text) & "/" & (aMonth + 1) as text) & "/1" else set eDat to ((aYear + 1) as text) & "/" & (1 as text) & "/1" end if –set sDat to date aDat set eDat to date eDat set eDat to eDat - 1 set mLen to day of eDat return mLen end getMlen |
|
▼新規書類に ▼カーソル位置に ▼ドキュメント末尾に
|
Posted in リスト処理(list), 日付、カレンダー関連(calendar), 10.5対応, 10.6対応, 10.4対応 | No Comments »
2行に別れているデータを1行分にまとめるAppleScriptです。
Excel上の選択範囲からデータを取得し、その内容が2行でワンセットになっているような場合に、2行目に存在しているデータについては1行目のアイテムにリストとして統合するものです。
たとえば、
{{”4″, “56″, “52″}, {”", “64″, “61″}}
というデータがあったとして、これを本AppleScriptで処理すると……
{{”4″, {”56″, “64″}, {”52″, “61″}}}
という結果が得られます。
| スクリプト名:2行に別れているデータを1行分にまとめる |
set aList to {{"4", "56", "52"}, {"", "64", "61"}} set aLen to length of aList
set gList to {}
– repeat with i from 1 to aLen by 2 set line1List to contents of item i of aList set line2List to contents of item (i + 1) of aList –1データセット分を処理する set aaLen to length of line1List set aaList to {} repeat with ii from 1 to aaLen set line1item to contents of item ii of line1List set line2item to contents of item ii of line2List if line2item is not equal to "" then set the end of aaList to {line1item, line2item} else set the end of aaList to line1item end if end repeat set the end of gList to aaList end repeat
gList –> {{"4", {"56", "64"}, {"52", "61"}}}
|
|
▼新規書類に ▼カーソル位置に ▼ドキュメント末尾に
|
Posted in リスト処理(list), 10.5対応, 10.6対応, 10.4対応 | No Comments »
リストで与えられたデータの変動ベクトル方向を取得するAppleScriptです。
……こう書くと何のことやら分かりませんが、かなり具体的なニーズに応えるために作成したものです。
Illustrator上でグラフを作成し、グラフのマーカーに近接して数値情報を配置しようとしたときに、グラフの線と重ならないように数値情報を配置することが必要になりました。
そこで、グラフの値が上昇している部分なのか、下降している部分なのか……といった傾向の判断を行うためにこうしたデータを作成し、さらにグラフの左右の端にあるかどうかなどのデータを取得して総合的に位置決めを行うことにした次第。
こうしたデータの変動ベクトル方向を求めるという用途は意外にたくさんあり、自分は割とよく使う処理です。
Illustratorのグラフ機能は貧弱で、どうせそのままでは使い物にならないので、GUI Scripting経由でAppleScriptからデータを突っ込んで、グラフオブジェクトをグループ解除して「ただのpath item」にまで分解してから料理しています。データを差し替えるとグラフのマーカーが変わってしまったとしても、分解してしまえば大丈夫です。
| スクリプト名:リストで与えられたデータの変動ベクトル方向を取得する |
set aList to {0.325, 0.4, 0.35, 0.012, 0.025, 0.55}
set curItem to first item of aList set aList to rest of aList
set trendList to {}
repeat with i in aList if curItem < i then set aTrend to “u” else if curItem > i then set aTrend to “d” else aTrend to “-” end if set the end of trendList to aTrend copy i to curItem end repeat
trendList –> {”u”, “d”, “d”, “u”, “u”} |
|
▼新規書類に ▼カーソル位置に ▼ドキュメント末尾に
|
Posted in リスト処理(list), 10.5対応, 10.6対応, 10.4対応 | No Comments »
与えられたリストの項目数をプロパティ(maxRow)で指定した数と比較し、足りない分はヌル要素を追加して、最終的にタブで区切ったテキストに変換するAppleScriptです。
Illustratorでグラフデータを連続自動作成する処理で、グラフに与えるデータを作成したものです。
| スクリプト名:リストの項目数をそろえてタブで区切ったテキストに変換する |
set maxRow to 9 –最大項目数 set aList to {40, 30, 20, 10}
–項目数が足りない場合には項目を追加する set outStr to "" set itemC to count every item of aList if itemC < maxRow then repeat (maxRow - itemC) times set aList to aList & 0 end repeat end if –> {40, 30, 20, 10, 0, 0, 0, 0, 0}
–リストを指定デリミタでテキスト化 set sList to {} repeat with i in aList set j to contents of i –このあたりで、適度にデータ加工するとよさそう(指定桁以下の切り捨てとか四捨五入とか) if j = 0 then set jj to "" else set jj to j as string end if set the end of sList to jj end repeat –> {"40", "30", "20", "10", "", "", "", "", ""}
set resStr to retDelimedText(sList, tab) of me –> "40 30 20 10 "
–リストを指定デリミタでテキスト化 on retDelimitedText(aList, aNewDelim) set aText to "" set curDelim to AppleScript’s text item delimiters set AppleScript’s text item delimiters to aNewDelim set aText to aList as text set AppleScript’s text item delimiters to curDelim return aText end retDelimitedText
|
|
▼新規書類に ▼カーソル位置に ▼ドキュメント末尾に
|
Posted in リスト処理(list), 10.5対応, 10.6対応, 10.4対応 | No Comments »
2つのリスト同士を比較して、相互に存在しない要素をピックアップします。いわゆる、リスト間のdiffをとるAppleScriptです。
正直なところ、相当昔(2〜3年ぐらい昔)に作ったので処理の細部を覚えていないのですが……なにげに途中に不思議な処理(なぜか同じ置換処理を2回行っている……)があったりします。1行だけにしても、置換処理そのものをコメントアウトしても問題なく動いているので、何か込み入ったデータを喰わせた際の対策だったのかもしれません。
<追記>
HTMLに書き出してはじめて分かりましたが、スペースの置換とタブの置換を行っていたようです。いやはや。
</追記ここまで>
例によって汎用サブルーチンを組み合わせて作ったため、「diffをとる」という単純で簡素な目的とはそぐわないほどの行数になっていますが、短時間で作ったためにそうなったものとご理解ください。
| スクリプト名:リスト同士のdiffをとる |
set aList to {1, 2, 3, 4, 0, 9, 10, 11} set bList to {4, 3, 2, 1, 5, 10} set aRes to diffList(aList, bList) of listDiffKit –> {{0, 9, 11}, {5}}
set aList to {“abc”, “cde”, “def”} set bList to {“abc”, “cde”, “def”, “ddd”} set aRes to diffList(aList, bList) of listDiffKit –> {{}, {”ddd”}}
set aList to {“ぴよ”, “ひよ”, “ビよ”, “よよ”} set bList to {“ビよ”, “ひよ”, “ぴよ”, “ぱよ”} set aRes to diffList(aList, bList) of listDiffKit –>{{”よよ”}, {”ぱよ”}}
script listDiffKit –リスト同士のdiffをとる on diffList(aaList, bbList) copy {aaList, bbList} to {aList, bList} –fix? set notExistInBlist to {} if aList is equal to bList then return {{}, {}} end if set aListText to (retDelimedText(aList, “|”) of me) as Unicode text set aListText to repChar(aListText, “ ” as Unicode text, “”) of me set aListText to repChar(aListText, ” “ as Unicode text, “”) of me –????? set bListText to (retDelimedText(bList, “|”) of me) as Unicode text set bListText to repChar(bListText, “ ” as Unicode text, “”) of me set bListText to repChar(bListText, ” “ as Unicode text, “”) of me –????? if aListText is equal to bListText then return {{}, {}} end if repeat with i in aList set j to contents of i if j is in bList or j is equal to bList then set bList to deleteSpecifiedItemFromList(bList, j) of me else set the end of notExistInBlist to j end if end repeat return {notExistInBlist, bList} end diffList –指定内容の要素をリストから削除して返す on deleteSpecifiedItemFromList(aList, anItem) set iCount to 1 repeat with i in aList set j to contents of i if j = anItem then set aaList to oneItemDelete(aList, iCount) of me return aaList end if set iCount to iCount + 1 end repeat return aList end deleteSpecifiedItemFromList –リスト中の指定要素を削除して返す on oneItemDelete(aList, chgNum) set newList to {} set aLen to length of aList if chgNum = 1 then set aLen to length of aList if aLen > 1 then set maeList to items 2 thru aLen of aList set newList to maeList else set newList to {} end if else if chgNum = aLen then set maeList to items 1 thru (aLen - 1) of aList set newList to maeList else set maeList to items 1 thru (chgNum - 1) of aList set atoList to items (chgNum + 1) thru -1 of aList set newList to maeList & atoList end if return newList end oneItemDelete on retDelimedText(aList, aDelim) set aText to “” set curDelim to AppleScript’s text item delimiters set AppleScript’s text item delimiters to aDelim set aText to aList as text set AppleScript’s text item delimiters to curDelim return aText end retDelimedText –文字置換ルーチン on repChar(origText, targStr, repStr) set {txdl, AppleScript’s text item delimiters} to {AppleScript’s text item delimiters, targStr} set temp to text items of origText set AppleScript’s text item delimiters to repStr set res to temp as text set AppleScript’s text item delimiters to txdl return res end repChar end script
|
|
▼新規書類に ▼カーソル位置に ▼ドキュメント末尾に
|
Posted in リスト処理(list), 10.5対応, 10.6対応, 10.4対応 | No Comments »
入れ子になっているリストから、要素中の指定アイテムの値が連続して同じ値で続くブロックを検出するAppleScriptです。
{{”ぴよぴよ”, 123}, {”ぴよぴよ”, 125}, {”ぴよぴよ”, 127}, {”ぴよりん”, 200}, {”ぴよきち”, 210}, {”ぴよこ”, 230}, {”ぴよこ”, 231}}
のようなリストがあったときに、各要素の第1項目が連続している箇所の始点アイテムと終点アイテムをペアにして返します。
膨大なデータのソーティングを行ったときに作ったもので、項目が重複している場合には別項目をキーにして重複部分のみ再ソートして返すようにしていました。
プログラム中でグローバル宣言を行っているのは、もともとの記述からa reference toによる変数への間接アクセスを行うようにしたためで、これをやるのとやらないのとではデータ数が増えたときのスピードがケタ違いです。
| スクリプト名:入れ子のリストから、指定アイテムの値が連続して同じ値で続くブロックを検出する |
global subA01List, subA01List_r
set aDataList to {{"ぴよぴよ", 123}, {"ぴよぴよ", 125}, {"ぴよぴよ", 127}, {"ぴよりん", 200}, {"ぴよきち", 210}, {"ぴよこ", 230}, {"ぴよこ", 231}} set rList to detectSuccessBlock(aDataList, 1) of me –> {{1, 3}, {6, 7}}
–アイテムitemNoの値が連続して同じ値で続くブロックを検出する –aDataListには、{item1,item2}の形式でデータが入っている。値の検出を行うのはitem1の部分のみ on detectSuccessBlock(aDataList, itemNo) copy aDataList to subA01List set aFlag to "" set blockListSub to {} – ブロック分割のすべてを記録しておく変数 set blockListSub_r to a reference to blockListSub set blockItem to {} –小ブロックの記録変数 set sFlag to false set prevItem to item itemNo of first item of subA01List set subA01List to rest of subA01List set iCount to 1 set subA01List_r to a reference to subA01List repeat with i in subA01List_r set curItem to contents of item itemNo of i if (prevItem as string) = (curItem as string) then if sFlag = false then –これまではブロック中にはいなかった。新たに値が連続するブロックを検出した set blockItem to {iCount} else –連続したブロック中にいる。継続して同じ値が続いている end if set sFlag to true else if sFlag = false then –これまでも連続ブロック中にはいなかった else –直前まで連続ブロックの中をスキャンしていた –連続ブロックの末尾を見つけた set the end of blockItem to iCount set the end of blockListSub to blockItem set blockItem to {} –ブロック保持用リストをクリア(ブロック末尾を検出したため) end if set sFlag to false end if set prevItem to curItem set iCount to iCount + 1 end repeat –連続ブロックが継続したままになっていた場合の処理 –末尾に存在していた連続ブロックを検出する if sFlag = true and blockItem is not equal to {} then set the end of blockItem to iCount set the end of blockListSub to blockItem end if return blockListSub end detectSuccessBlock
|
|
▼新規書類に ▼カーソル位置に ▼ドキュメント末尾に
|
Posted in リスト処理(list), 10.5対応, 10.6対応, 10.4対応 | No Comments »
指定の数字の組み合わせのすべてのパターンをリストアップするAppleScriptです。
あるアプリケーションでGUI側からパラメータを変更して、すべての組み合わせパターンについて総当たりで計算を行い、その計算結果をパラメータ入りのファイル名で保存したい。そんなときに、各パラメータのすべての組み合わせからなる特定桁の数のすべての組み合わせを算出……………
ああ、めんどくさい〜。考えていたらまじめに計算するのがバカバカしくなってきました。
そこで、発想の大転換。
指定桁の数値をすべて作成しておいて、ループで条件に合うものだけをピックアップすればよいのではないか、と。コンピュータのCPUパワーにモノを言わせて抽出するように路線転換してみました。
作ってみると……たしかに、プログラムは簡単。一応、チェックしてみましたが、組み合わせ数もきっちり合っています。
5つの数値パラメータから構成される数字の組み合わせを計算するために、10000〜99999までの89999個のシーケンシャル・ナンバーを作成し、パラメータの範囲を入れたリストをもとに条件にすべて合うものだけを抽出。
| スクリプト名:指定の数字の組み合わせのすべてのパターンをリストアップ |
set aTime to current date
set aList to {} set aList_r to a reference to aList
set bList to {} set bList_r to a reference to bList
set okList to {{1, 2}, {1, 2, 3}, {0, 1}, {1, 2, 3, 4}, {1, 2, 3, 4, 5, 6, 7, 8}} set okL_r to a reference to okList
–指定桁数の数字をジェネレートする repeat with i from 10000 to 99999 set the end of aList_r to i end repeat
–生成した数字リストを評価 repeat with i in aList_r set j to i as string set cList to characters of j set cLen to length of cList set hitF to true repeat with ii from 1 to cLen if (item ii of cList) as number is not in (item ii of okL_r) then set hitF to false exit repeat end if end repeat –条件にすべて合ったものだけピックアップ if hitF = true then set the end of bList_r to contents of i end if end repeat
set bTIme to current date set cTIme to bTIme - aTime |
|
▼新規書類に ▼カーソル位置に ▼ドキュメント末尾に
|
結局、384個のデータを抽出。Core i7 2.66GHzのMacBook Proで7秒ほどかかりました。まあ、このぐらいで計算できたら上出来でしょう。さらにこれを4スレッドぐらいの並列処理で同時に計算したら、3秒ぐらいで終わりそうですが……
実際に処理対象の分布図を描いてみると、ほとんどが無駄な演算になってしまうので、この「無駄な演算」をどれだけ減らせるかが処理速度向上のキーポイントになります。
そこで、最上位桁にあてはまる数字に着目。ここが1つ違うだけでも1万データもかわってくるので、最上位桁だけに着目しただけでも、計算範囲を大幅に絞ることができ、大幅に処理高速化ができそうです。
ちなみに、最上位桁に入る最大の数字が2であれば…………残りの3〜9の可能性はすべて捨てて考えることができるわけで、処理対象データは89999個から19999個へと大幅に減らせます。処理対象データが80%減れば、処理速度はおのずと向上します。
実際に試してみたら、2秒で処理完了。なかなか、いい感じです。
| スクリプト名:指定の数字の組み合わせのすべてのパターンをリストアップ v2 |
set aTime to current date
set aList to {} set aList_r to a reference to aList
set bList to {} set bList_r to a reference to bList
set okList to {{1, 2}, {1, 2, 3}, {0, 1}, {1, 2, 3, 4}, {1, 2, 3, 4, 5, 6, 7, 8}} set okL_r to a reference to okList
set paramLen to length of okList
set maxDigitNum to (last item of first item of okList)
set fromNum to “1″ repeat paramLen - 1 times set fromNum to fromNum & “0″ end repeat set fromNum to fromNum as number
set toNum to maxDigitNum as string repeat paramLen - 1 times set toNum to toNum & “9″ end repeat set toNum to toNum as number
–指定桁数の数字をジェネレートする repeat with i from fromNum to toNum set the end of aList_r to i end repeat
–生成した数字リストを評価 repeat with i in aList_r set j to i as string set cList to characters of j set cLen to length of cList set hitF to true repeat with ii from 1 to cLen if (item ii of cList) as number is not in (item ii of okL_r) then set hitF to false exit repeat end if end repeat –条件にすべて合ったものだけピックアップ if hitF = true then set the end of bList_r to contents of i end if end repeat
set bTIme to current date set cTIme to bTIme - aTime
|
|
▼新規書類に ▼カーソル位置に ▼ドキュメント末尾に
|
Posted in リスト処理(list), アプリケーション操作(app control), 10.5対応, 10.6対応, 10.4対応 | No Comments »
数値リストを連続する部分ごとに「起点」「終点」ペアのリストに分解します。
InDesignで文字書式を変更する際に、characterを1つずつ処理していては時間の無駄なので、起点と終点を指定して書式を変更する改良を加えた際に使用しました。
本ルーチンの投入により、10倍以上の高速化に成功しました。文字数が多くなればなるほど差がつくはずです。
| スクリプト名:数値リストを連続部分に分解する |
set cNumList to {40, 41, 42, 43, 44, 45, 46, 47, 48, 63, 64, 85, 86, 88, 89, 90, 107, 108, 109, 110, 111, 112, 113, 114, 115} set nList to splitNumList(cNumList) of me –> {{40, 48}, {63, 64}, {85, 86}, {88, 90}, {107, 115}}
set cNumList to {54, 55, 56, 57, 58, 59, 60, 61, 62} set nList to splitNumList(cNumList) of me –> {{54, 62}}
–数値リストを、連続する値ごとにペアで「起点」「終点」リストにして返す on splitNumList(cNumList) set bList to detectChangeInNumSeriesList(cNumList) of me if length of bList is not equal to 1 then set prevItem to contents of first item of bList set bList to rest of bList set outList to {{1, prevItem}} repeat with i in bList set j1 to prevItem + 1 set j2 to contents of i set the end of outList to {j1, j2} set prevItem to j2 end repeat set aLen to length of cNumList if j2 is not equal to aLen then set the end of outList to {j2 + 1, aLen} end if else set outList to {contents of first item of bList} end if set newList to {} repeat with i in outList set j1 to item (item 1 of i) of cNumList set j2 to item (item 2 of i) of cNumList set the end of newList to {j1, j2} end repeat return newList end splitNumList
–数値リストで、値が連続しないポイントをアイテム番号のリストで返す on detectChangeInNumSeriesList(aNumList) set prevNum to (first item of aNumList) set bNumList to rest of aNumList set outList to {} set iCount to 1 repeat with i in bNumList set j to contents of i if prevNum = (j - 1) then – else set the end of outList to iCount end if copy j to prevNum set iCount to iCount + 1 end repeat if outList = {} then set outList to {{1, length of aNumList}} end if return outList end detectChangeInNumSeriesList |
|
▼新規書類に ▼カーソル位置に ▼ドキュメント末尾に
|
Posted in リスト処理(list), 10.5対応, 10.6対応, 10.4対応 | No Comments »
指定の矩形座標内に含まれる座標をリスト内からピックアップするAppleScriptです。
{y1, x1, y2, x2} 形式で指定した座標内に含まれる座標(InDesignから取得したgeometric bounds)をピックアップします。
スクリプトラベルのついていないText frameからデータを取り出しを行う必要があったときに、他のスクリプトラベルが付いているオブジェクトからの相対矩形座標内に存在するObjectを求めるようにしてみました。その時に試作したものです。
| スクリプト名:指定矩形座標内に含まれる座標をピックアップ |
set aList to {{243.0, 17.0, 245.0, 77.0}, {169.000015228534, 12.0, 187.500015228534, 166.999999999992}, {189.000007614311, 13.0, 242.000007614312, 17.0}, {188.999990448174, 17.0, 241.999990448174, 76.999999025133}, {188.999990448174, 87.5, 241.999990448174, 123.5}}
set rangeList to {236.999990448174, 12.0, 246.999990448174, 81.999999025133} –{y1,x1,y2,x2} set resList to withinRange_Y1X1Y2X2(rangeList, aList) of me
–指定矩形内に含まれるデータをリストで返す on withinRange_Y1X1Y2X2(rangeList, targetList) set includedList to {} set y1 to item 1 of rangeList set x1 to item 2 of rangeList set y2 to item 3 of rangeList set x2 to item 4 of rangeList repeat with i in targetList set targY1 to item 1 of i set targX1 to item 2 of i set targY2 to item 3 of i set targX2 to item 4 of i if (x1 < targX1) and (x2 > targX2) and (y1 < targY1) and (y2 > targY2) then set the end of includedList to (contents of i) end if end repeat return includedList end withinRange_Y1X1Y2X2
|
|
▼新規書類に ▼カーソル位置に ▼ドキュメント末尾に
|
Posted in リスト処理(list), 10.5対応, 10.6対応, 10.4対応 | No Comments »