AppleScript名:配列の要素を逆順に取得する |
— Created 2015-09-02 by Takaaki Naganoya — 2015 Piyomaru Software use AppleScript version "2.4" use scripting additions use framework "Foundation" set anArray to current application’s NSArray’s arrayWithArray:{1, 2, 3} –> (NSArray) {1, 2, 3} –要素を逆順に取得する set revEnum to anArray’s reverseObjectEnumerator() –> (__NSArrayReverseEnumerator) <__NSArrayReverseEnumerator: 0x610000a3c600> repeat set aValue to revEnum’s nextObject() if aValue = missing value then exit repeat log aValue as list of string or string end repeat |
カテゴリー: list
数値リストで指定数よりも大きな要素のみを抽出
AppleScript名:数値リストで指定数よりも大きな要素のみを抽出 |
— Created 2017-10-29 by Takaaki Naganoya — 2017 Piyomaru Software use AppleScript version "2.4" use scripting additions use framework "Foundation" set aList to {8, 2, 7, 3, 9, 1, 6, 4} set theArray to current application’s NSArray’s arrayWithArray:aList set thePred to current application’s NSPredicate’s predicateWithFormat:"self >= 4" set bList to (theArray’s filteredArrayUsingPredicate:thePred) as list –> {8, 7, 9, 6, 4} set thePred to current application’s NSPredicate’s predicateWithFormat:"self > 4" set cList to (theArray’s filteredArrayUsingPredicate:thePred) as list –> {8, 7, 9, 6} |
指定数ではない要素のみを抽出
AppleScript名:指定数ではない要素のみを抽出 |
— Created 2017-10-29 by Takaaki Naganoya — 2017 Piyomaru Software use AppleScript version "2.4" use scripting additions use framework "Foundation" set theArray to current application’s NSArray’s arrayWithArray:{8, 2, 7, 3, 9, 1, 6, 4} set thePred to current application’s NSPredicate’s predicateWithFormat:"(self != 2) AND (self != 4)" set bList to (theArray’s filteredArrayUsingPredicate:thePred) as list –> {8, 7, 3, 9, 1, 6} |
指定文字列ではじまる要素のみ抽出
AppleScript名:指定文字列ではじまる要素のみ抽出 |
— Created 2017-10-29 by Takaaki Naganoya — 2017 Piyomaru Software use AppleScript version "2.4" use scripting additions use framework "Foundation" set stringArray to current application’s NSArray’s arrayWithArray:{"adobe", "Apple", "microsoft", "google"} set thePred to current application’s NSPredicate’s predicateWithFormat:"self BEGINSWITH ’a’" set bList to (stringArray’s filteredArrayUsingPredicate:thePred) as list –> {"adobe"} |
指定文字列ではじまる要素のみ抽出(大文字、小文字を問わず)
AppleScript名:指定文字列ではじまる要素のみ抽出(大文字、小文字を問わず) |
— Created 2017-10-29 by Takaaki Naganoya — 2017 Piyomaru Software use AppleScript version "2.4" use scripting additions use framework "Foundation" set stringArray to current application’s NSArray’s arrayWithArray:{"adobe", "Apple", "microsoft", "google"} set thePred to current application’s NSPredicate’s predicateWithFormat:"self BEGINSWITH[cd] ’A’" set bList to (stringArray’s filteredArrayUsingPredicate:thePred) as list –> {"adobe", "Apple"} |
指定文字列ではじまる要素のみ抽出(ワイルドカード使用)
1Dリスト(1次元配列)に入っているデータを、Cocoaのオブジェクトに変換してワイルドカードで指定要素を抽出するAppleScriptです。
割と短く書けるので、幅広く使いたくなるところですが……処理速度がそれほど速くありません。これだと、AppleScriptのリスト(配列)型変数をループで条件判定して抽出したほうが速く処理できそうです。
データ件数が増えた場合にはAppleScriptネイティブの配列とCocoaの配列(NSArray)で速度比較して、Cocoaのオブジェクトを使って高速になる条件はどこかにあると思われますが、少なくとも要素数が5個ぐらいの「おかわいらしい」サイズの配列変数だとAppleScriptネイティブのオブジェクトを使って地道にループで判定したほうが高速です。
AppleScript名:指定文字列ではじまる要素のみ抽出(ワイルドカード使用) |
— Created 2017-10-29 by Takaaki Naganoya — 2017 Piyomaru Software use AppleScript version "2.4" use scripting additions use framework "Foundation" set stringArray to current application’s NSArray’s arrayWithArray:{"adobe", "Apple", "microsoft", "google"} set thePred to current application’s NSPredicate’s predicateWithFormat:"self LIKE ’Ap*’" set bList to (stringArray’s filteredArrayUsingPredicate:thePred) as list –> {"Apple"} |
AppleScript名:指定文字列ではじまる要素のみ抽出(ワイルドカード使用、レコード) |
— Created 2017-10-29 by Takaaki Naganoya — 2017 Piyomaru Software use AppleScript version "2.4" use scripting additions use framework "Foundation" set aRecList to {{aName:"adobe", anID:1}, {aName:"Apple", anID:2}, {aName:"microsoft", anID:3}, {aName:"google", anID:4}} set stringArray to current application’s NSArray’s arrayWithArray:aRecList set thePred to current application’s NSPredicate’s predicateWithFormat:"aName LIKE ’Ap*’" set bList to (stringArray’s filteredArrayUsingPredicate:thePred) as list –> {{aName:"Apple", anID:2}} |
指定リストから、Regexpで要素を抽出
AppleScript名:指定リストから、Regexpで要素を抽出 |
— Created 2017-10-29 by Takaaki Naganoya — 2017 Piyomaru Software use AppleScript version "2.4" use scripting additions use framework "Foundation" set stringArray to current application’s NSArray’s arrayWithArray:{"adobe", "22", "microsoft", "99"} set thePred to current application’s NSPredicate’s predicateWithFormat:"self MATCHES ’\\\\d\\\\d’" set bList to (stringArray’s filteredArrayUsingPredicate:thePred) as list –> {"22", "99"} |
指定リストから、文字数で要素を抽出
AppleScript名:指定リストから、文字数で要素を抽出 |
— Created 2017-10-29 by Takaaki Naganoya — 2017 Piyomaru Software use AppleScript version "2.4" use scripting additions use framework "Foundation" set stringArray to current application’s NSArray’s arrayWithArray:{"adobe", "22", "microsoft", "99"} set thePred to current application’s NSPredicate’s predicateWithFormat:"self.length > 5" set bList to (stringArray’s filteredArrayUsingPredicate:thePred) as list –> {"microsoft"} |
配列を逆順に(OLD Style AS)
AppleScriptネイティブの配列変数であるlist型変数を逆順にするAppleScriptです。
配列(list)の要素数が5,000以下ぐらいだと普通に変数に保持して、このように逆順に変換して配列に代入するのが一番速いでしょう。
配列(list)の要素数が5,000以上ぐらいだとscriptオブジェクト内に格納したpropertyに保持して、このように逆順に変換してpropertyに代入するのが一番速いでしょう。
Cocoaの配列変数(NSArray、NSMutableArray)に格納して速度面での優位性が生まれてくるのは、要素数が1万とか数十万アイテムぐらいになった場合です。
Cocoa Scriptingで予想外にパフォーマンスが出ないケースというのは、たいてい配列処理で件数が少なすぎて逆効果だったという場合が多いので、ネイティブのAppleScriptのlist型変数の各種処理も重要です。
AppleScript名:配列を逆順に(OLD Style AS) |
— Created 2017-07-30 by Takaaki Naganoya — 2017 Piyomaru Software set aList to {1, 2, 3, 4, 5, 6} set revArray to reverse of aList –> {6, 5, 4, 3, 2, 1} |
複数キーによるソートテスト3.1(OLD Style AppleScript)
OLD Style AppleScriptによる2D Listの複数キーによるソートを行うAppleScriptです。
以前掲載したソートルーチンの速度比較で、2D ArrayのソートでOLD Style AppleScript版はSingle Keyのルーチンでしたが、本来であればこのMulti-Keyのルーチンで比較を行うべきでした。
ASOC版はMulti-Keyのソートルーチンなので、2.0 vs 0.3 secondsというところ。
AppleScript名:複数キーによるソートテスト3.1 |
–複数キーによるソートテスト3(複数キーを許容。キー数無制限) script orig property aList : {} end script –テストデータ作成 set aList of orig to {} repeat 10000 times –3次まですべてのキーを使ったソートが発生するよう、1次、2次キーは乱数範囲をわざと狭くしてある set the end of aList of orig to {"a", random number from 1 to 10, random number from 1 to 10, random number from 1 to 100} end repeat set sDat to current date –ソート時間計測(開始時刻) –item 2をPrimary key、item 3とitem 4をサブキーにして降順ソート set resList to multiKeySortDescending(aList of orig, {2, 3, 4}) of multiKeySort set eDat to current date –ソート時間計測(終了時刻) return (eDat – sDat) –複数キーによるソート script multiKeySort script spd property bList : {} –1次キーでソートした結果が入る property cList : {} –1次キーでソートした結果のうち、1次キーで同じ値が連続する範囲が入る {{1,3},{10,20}} property dList : {} –2次キーで再ソートする対象の一部のリストが入る(ワーク用) property eList : {} –2次キーで再ソートした結果のリストが入る(ワーク用) end script –複数キー(Primary, Secondary……)による降順ソート。キーは指定用のリストに入れる –falseが返ってきたらエラー on multiKeySortDescending(aList, keyList) –Initialize –set aList of spd to {} set bList of spd to {} –■■■■ ここからパラメータのチェック ■■■■ –型チェック set aLen to length of keyList if class of keyList is not equal to list then return false –キー値のリストがlistではなかった場合error end if –ソート対象の2D Listの要素数を取得 set tmpLen to length of first item of aList repeat with i in keyList if i > tmpLen then return false –キー値として指定した内容が、ソート対象のリストの要素数よりも大きかった場合error end if end repeat –キー指定内容で重複がないかチェック set dupList to detectDuplicates(keyList) of me if dupList is not equal to {} then return false –指定したキーで重複があったらerror end if –キー指定内容に0が入っていないかチェック if 0 is in keyList then return false –■■■■ パラメータのチェックここまで ■■■■ set firstKeyNo to first item of keyList –1次キーで2D Listをソート(降順) set bList of spd to shellSortListDescending(aList, firstKeyNo) of me –複数キーによるソート検証および実行ループ repeat with iii from 1 to aLen – 1 set cList of spd to {} set dList of spd to {} set eList of spd to {} –n次キーの値が連続する箇所を探す set curData to missing value set sucF to false –データ連続箇所検出中フラグ(false=非連続、true=連続中) set biginItem to 0 set endItem to 0 set itemC to 0 repeat with i in bList of spd set thisData to item (item iii of keyList) of i –n次キー –現在の値と前の値が等しい(連続箇所を検出した、あるいは連続箇所の中にいる) if curData = thisData then if sucF = false then set biginItem to itemC set sucF to true else if sucF = true then –連続箇所の検索継続中、何もしない end if else –現在の値と前の値が等しくない(連続していない、あるいは連続箇所の末尾を検出した) if sucF = true then set the end of cList of spd to {biginItem, itemC} set sucF to false end if set curData to thisData end if set itemC to itemC + 1 end repeat –n次キーの連続状態の検出中のままリスト末尾に来た場合には、最終データを出力する if sucF = true and curData = thisData then set the end of cList of spd to {biginItem, itemC} end if –n次キーによる重複箇所がない場合には、n次キーによるソート結果をそのまま返す if cList of spd = {} then return bList of spd end if –n+1次キーによる部分ソートし直し repeat with i in cList of spd set {tmpB, tmpE} to i copy items tmpB thru tmpE of (bList of spd) to (dList of spd) set (eList of spd) to shellSortListDescending((dList of spd), (item (iii + 1) of keyList)) of me set tmpCounter to 1 repeat with ii from tmpB to tmpE copy item tmpCounter of (eList of spd) to item ii of (bList of spd) set tmpCounter to tmpCounter + 1 end repeat end repeat end repeat return (bList of spd) end multiKeySortDescending –リスト中から重複項目をリストアップする on detectDuplicates(aList) set aCount to length of aList set duplicationList to {} repeat aCount times set anItem to contents of (first item of aList) set aList to rest of aList if anItem is in aList then set the end of duplicationList to anItem end if end repeat return duplicationList end detectDuplicates –シェルソートで入れ子のリストを降順ソート on shellSortListDescending(aSortList, aKeyItem) script oBj property list : aSortList end script set len to count oBj’s list’s items set gap to 1 repeat while (gap ≤ len) set gap to ((gap * 3) + 1) end repeat repeat while (gap > 0) set gap to (gap div 3) if (gap < len) then repeat with i from gap to (len – 1) set temp to oBj’s list’s item (i + 1) set j to i repeat while ((j ≥ gap) and (contents of item aKeyItem of (oBj’s list’s item (j – gap + 1)) < item aKeyItem of temp)) set oBj’s list’s item (j + 1) to oBj’s list’s item (j – gap + 1) set j to j – gap end repeat set oBj’s list’s item (j + 1) to temp end repeat end if end repeat return oBj’s list end shellSortListDescending end script |
iTunesライブラリの曲のアーティスト名を集計
iTunesライブラリ中の曲のアーティスト名を集計して、曲数が多い順に集計するAppleScriptです。
アーティスト名のFirst NameとLast Nameの間にスペースが存在している場合としていない場合が(iTunes Music Storeからダウンロード購入した曲でも)混在していたので、こうしたデータのゆらぎに対処しています。
6,827曲のライブラリの集計が、筆者の開発環境(MacBook Pro Retina 2012 Core i7 2.66GHz)で2.7秒ぐらいです。
AppleScript名:iTunesライブラリの曲のアーティスト名を集計 |
— Created 2017-01-07 by Takaaki Naganoya — 2017 Piyomaru Software use AppleScript version "2.4" use scripting additions use framework "Foundation" use framework "iTunesLibrary" set library to current application’s ITLibrary’s libraryWithAPIVersion:"1.0" |error|:(missing value) if library is equal to missing value then return set allTracks to library’s allMediaItems() set allCount to allTracks’s |count|() set anEnu to allTracks’s objectEnumerator() set newArray to current application’s NSMutableArray’s alloc()’s init() repeat set aPL to anEnu’s nextObject() if aPL = missing value then exit repeat try set aKind to (aPL’s mediaKind) as integer if (aKind as integer) is equal to 2 then –Music, Song set plName to aPL’s artist’s |name| as string set pl2Name to (my changeThis:" " toThat:"" inString:plName) –日本語アーティスト名で姓と名の間にスペースが入っているものがある(表記ゆらぎ)ので対策 newArray’s addObject:(pl2Name) end if on error set aLoc to (aPL’s location’s |path|()) as string –log aLoc end try end repeat set aRes to countItemsByItsAppearance(newArray) of me –> {{theName:"浜田省吾", numberOfTimes:442}, {theName:"B’z", numberOfTimes:379}, {theName:"渡辺岳夫・松山祐士", numberOfTimes:199}, {theName:"VariousArtists", numberOfTimes:192}, {theName:"菅野よう子", numberOfTimes:108}, {theName:"布袋寅泰", numberOfTimes:100}, {theName:"三枝成彰", numberOfTimes:95}, {theName:"宇多田ヒカル", numberOfTimes:94}, {theName:"宮川泰", numberOfTimes:81}, {theName:"MichaelJackson", numberOfTimes:78}, {theName:"稲葉浩志", numberOfTimes:73}, … –出現回数で集計 on countItemsByItsAppearance(aList) set aSet to current application’s NSCountedSet’s alloc()’s initWithArray:aList set bArray to current application’s NSMutableArray’s array() set theEnumerator to aSet’s objectEnumerator() repeat set aValue to theEnumerator’s nextObject() if aValue is missing value then exit repeat bArray’s addObject:(current application’s NSDictionary’s dictionaryWithObjects:{aValue, (aSet’s countForObject:aValue)} forKeys:{"theName", "numberOfTimes"}) end repeat –出現回数(numberOfTimes)で降順ソート set theDesc to current application’s NSSortDescriptor’s sortDescriptorWithKey:"numberOfTimes" ascending:false bArray’s sortUsingDescriptors:{theDesc} return bArray as list end countItemsByItsAppearance on changeThis:findString toThat:repString inString:someText set theString to current application’s NSString’s stringWithString:someText set theString to theString’s stringByReplacingOccurrencesOfString:findString withString:repString options:(current application’s NSRegularExpressionSearch) range:{location:0, |length|:length of someText} return theString as text end changeThis:toThat:inString: |
MatRによる行列計算テスト v4
–> download sample data ”matrix.txt”
AppleScript名:MatRによる行列計算テスト v4 |
— Created 2017-05-15 by Takaaki Naganoya — 2017 Piyomaru Software use AppleScript version "2.4" use scripting additions use framework "Foundation" use framework "DCMatrix" –https://github.com/davidcox95/MatR –タブ区切りテキストファイルからMatrixを作る set aPosixFile to POSIX path of (choose file) set aMatrix to current application’s |Matrix|’s alloc()’s initWithContentsFromFile:aPosixFile aMatrix’s |print|() (* 5 6 7 8 3 4 5 6 1 2 3 4 *) |
MatRによる行列計算テスト v3
AppleScript名:MatRによる行列計算テスト v3 |
— Created 2017-05-15 by Takaaki Naganoya — 2017 Piyomaru Software use AppleScript version "2.4" use scripting additions use framework "Foundation" use framework "DCMatrix" –https://github.com/davidcox95/MatR –listからMatrixを作る set mList to {{1, 2, 3, 4}, {11, 12, 13, 14}, {21, 22, 23, 24}} set aMatrix to current application’s |Matrix|’s alloc()’s initWithArray:mList andRows:3 byColumns:4 aMatrix’s |print|() (* 1 2 3 4 11 12 13 14 21 22 23 24 *) set a1Res to aMatrix’s |transpose|() (a1Res’s |print|()) (* 1 11 21 2 12 22 3 13 23 4 14 24 *) |
MatRによる行列計算テスト v2
AppleScript名:MatRによる行列計算テスト v2 |
— Created 2017-05-15 by Takaaki Naganoya — 2017 Piyomaru Software use AppleScript version "2.4" use scripting additions use framework "Foundation" use framework "DCMatrix" –https://github.com/davidcox95/MatR –行列データをdoubleのListに set aMatrix to current application’s |Matrix|’s alloc()’s initWithValue:(current application’s NSNumber’s numberWithDouble:5) andRows:3 byColumns:4 set aList to doubleListFromMatrix(aMatrix) of me –> {{5.0, 5.0, 5.0, 5.0}, {5.0, 5.0, 5.0, 5.0}, {5.0, 5.0, 5.0, 5.0}} –行列データをintegerのListに set bList to intListFromMatrix(aMatrix) of me –> {{5, 5, 5, 5}, {5, 5, 5, 5}, {5, 5, 5, 5}} –行列データをstringのListに set cList to strListFromMatrix(aMatrix) of me –> {{"5", "5", "5", "5"}, {"5", "5", "5", "5"}, {"5", "5", "5", "5"}} set bMatrix to current application’s |Matrix|’s alloc()’s initWithValue:(current application’s NSNumber’s numberWithDouble:3) andRows:4 byColumns:3 set bScalar to current application’s NSNumber’s numberWithDouble:2 set bRes to bMatrix’s addScalar:bScalar set bbRes to intListFromMatrix(bRes) of me –> {{5, 5, 5}, {5, 5, 5}, {5, 5, 5}, {5, 5, 5}} set cScalar to current application’s NSNumber’s numberWithDouble:2 set cRes to bMatrix’s subtractScalar:cScalar set ccRes to intListFromMatrix(cRes) of me –> {{1, 1, 1}, {1, 1, 1}, {1, 1, 1}, {1, 1, 1}} set dScalar to current application’s NSNumber’s numberWithDouble:2 set eRes to bMatrix’s multiplyScalar:dScalar set eeRes to intListFromMatrix(eRes) of me –> {{6, 6, 6}, {6, 6, 6}, {6, 6, 6}, {6, 6, 6}} set fScalar to current application’s NSNumber’s numberWithDouble:2 set fRes to bMatrix’s divideScalar:fScalar set ffRes to doubleListFromMatrix(fRes) of me –> {{1.5, 1.5, 1.5}, {1.5, 1.5, 1.5}, {1.5, 1.5, 1.5}, {1.5, 1.5, 1.5}} set m4 to current application’s |Matrix|’s alloc()’s initWithValue:(current application’s NSNumber’s numberWithDouble:4) andRows:3 byColumns:3 set m2 to current application’s |Matrix|’s alloc()’s initWithValue:(current application’s NSNumber’s numberWithDouble:2) andRows:3 byColumns:3 set gRes to m4’s addMatrix:m2 set ggRes to intListFromMatrix(gRes) of me –> {{6, 6, 6}, {6, 6, 6}, {6, 6, 6}} set hRes to m4’s subtractMatrix:m2 set hhRes to intListFromMatrix(hRes) of me –> {{2, 2, 2}, {2, 2, 2}, {2, 2, 2}} set iRes to m4’s multiplyMatrix:m2 set iiRes to intListFromMatrix(iRes) of me –> {{24, 24, 24}, {24, 24, 24}, {24, 24, 24 on doubleListFromMatrix(aMatrix) set aList to {} set aRows to aMatrix’s rows() set aColumns to aMatrix’s columns() repeat with rowC from 0 to (aRows – 1) set colList to {} repeat with colC from 0 to (aColumns – 1) set the end of colList to (aMatrix’s getElementAtRow:rowC andColumn:colC) as real end repeat set the end of aList to colList end repeat return aList end doubleListFromMatrix on intListFromMatrix(aMatrix) set aList to {} set aRows to aMatrix’s rows() set aColumns to aMatrix’s columns() repeat with rowC from 0 to (aRows – 1) set colList to {} repeat with colC from 0 to (aColumns – 1) set the end of colList to (aMatrix’s getElementAtRow:rowC andColumn:colC) as integer end repeat set the end of aList to colList end repeat return aList end intListFromMatrix on strListFromMatrix(aMatrix) set aList to {} set aRows to aMatrix’s rows() set aColumns to aMatrix’s columns() repeat with rowC from 0 to (aRows – 1) set colList to {} repeat with colC from 0 to (aColumns – 1) set the end of colList to (aMatrix’s getElementAtRow:rowC andColumn:colC) as string end repeat set the end of aList to colList end repeat return aList end strListFromMatrix |
MatRによる行列計算テスト v1
AppleScript名:MatRによる行列計算テスト v1 |
— Created 2017-05-15 by Takaaki Naganoya — 2017 Piyomaru Software use AppleScript version "2.4" use scripting additions use framework "Foundation" use framework "DCMatrix" –https://github.com/davidcox95/MatR –指定数値、指定サイズ(行、列)で行列データを作成する set aMatrix to current application’s |Matrix|’s alloc()’s initWithValue:(current application’s NSNumber’s numberWithDouble:5) andRows:3 byColumns:4 (aMatrix’s |print|()) (* 5 5 5 5 5 5 5 5 5 5 5 5 *) –行列データに数値を加算する set bMatrix to current application’s |Matrix|’s alloc()’s initWithValue:(current application’s NSNumber’s numberWithDouble:7) andRows:4 byColumns:3 set bScalar to current application’s NSNumber’s numberWithDouble:2 set bRes to bMatrix’s addScalar:bScalar bRes’s |print|() (* 9 9 9 9 9 9 9 9 9 9 9 9 *) –行列データから数値を減算する set cScalar to current application’s NSNumber’s numberWithDouble:3 set cRes to bMatrix’s subtractScalar:cScalar cRes’s |print|() (* 4 4 4 4 4 4 4 4 4 4 4 4 *) –行列データに数値を乗算する set dScalar to current application’s NSNumber’s numberWithDouble:2 set eRes to bMatrix’s multiplyScalar:dScalar eRes’s |print|() (* 14 14 14 14 14 14 14 14 14 14 14 14 *) –行列データに数値を除算する set fScalar to current application’s NSNumber’s numberWithDouble:2 set fRes to bMatrix’s divideScalar:fScalar fRes’s |print|() (* 3.5 3.5 3.5 3.5 3.5 3.5 3.5 3.5 3.5 3.5 3.5 3.5 *) –行列同士の加算 set m4 to current application’s |Matrix|’s alloc()’s initWithValue:(current application’s NSNumber’s numberWithDouble:4) andRows:3 byColumns:3 set m2 to current application’s |Matrix|’s alloc()’s initWithValue:(current application’s NSNumber’s numberWithDouble:2) andRows:3 byColumns:3 set gRes to m4’s addMatrix:m2 gRes’s |print|() (* 6 6 6 6 6 6 6 6 6 *) –行列同士の減算 set hRes to m4’s subtractMatrix:m2 hRes’s |print|() (* 2 2 2 2 2 2 2 2 2 *) –行列同士の乗算 set iRes to m4’s multiplyMatrix:m2 iRes’s |print|() (* 24 24 24 24 24 24 24 24 24 *) |
与えられたデータのうちIPアドレスとして妥当なもののみを抽出
AppleScript名:与えられたデータのうちIPアドレスとして妥当なもののみを抽出 |
— Created 2018-01-03 by Takaaki Naganoya — 2018 Piyomaru Software use AppleScript version "2.4" use scripting additions use framework "Foundation" property NSPredicate : a reference to current application’s NSPredicate property NSArray : a reference to current application’s NSArray set aaList to {"112.4.208.194", "17.20.30..12"} set aResList to {} repeat with i in aaList set j to contents of i set the end of aResList to chkIPAddressFormat(j) of me end repeat aResList on chkIPAddressFormat(aStr as string) set aList to {aStr} set anArray to NSArray’s arrayWithArray:aList set aPred to NSPredicate’s predicateWithFormat:"SELF MATCHES ’[0-9]{1,3}\\.[0-9]{1,3}\\.[0-9]{1,3}\\.[0-9]{1,3}’" set bRes to (anArray’s filteredArrayUsingPredicate:aPred) as list return (length of bRes = 1) as boolean end chkIPAddressFormat |
指定リストから、Regexpで要素を抽出(NSPredicate)
AppleScript名:指定リストから、Regexpで要素を抽出(NSPredicate) |
— Created 2017-10-29 by Takaaki Naganoya — 2017 Piyomaru Software use AppleScript version "2.4" use scripting additions use framework "Foundation" set stringArray to current application’s NSArray’s arrayWithArray:{"adobe", "22", "microsoft", "99"} set thePred to current application’s NSPredicate’s predicateWithFormat:"self MATCHES ’\\\\d\\\\d’" set bList to (stringArray’s filteredArrayUsingPredicate:thePred) as list –> {"22", "99"} |
同スコアを考慮した順位決定(汎用ルーチン)
AppleScript名:同スコアを考慮した順位決定(汎用ルーチン) |
use AppleScript version "2.4" use scripting additions set rList to {{"近 装甲強化型ジム COST: 200", 60}, {"遠 ジム・キャノン COST: 160", 39}, {"近 ジム・コマンド COST: 200", 32}, {"近 ジム(WD隊) COST: 160", 26}, {"近 陸戦型ガンダム COST: 220", 23}, {"近 ジム改 COST: 240", 22}, {"遠 ガンタンク COST: 200", 21}, {"格 ジム(指揮官機) COST: 160", 20}, {"近 ジム COST: 120", 19}, {"格 陸戦型ジム COST: 120", 10}, {"近 ジム・トレーナー COST: 120", 9}, {"射 ジム・スナイパーII(WD隊) COST: 220", 8}, {"射 陸戦型ガンダム(ジム頭) COST: 200", 7}, {"格 ガンダム COST: 280", 6}, {"近 ザクII(F2) COST: 160", 6}, {"格 ジム・ストライカー COST: 180", 4}, {"近 ジム・寒冷地仕様 COST: 200", 4}, {"狙 ジム・スナイパーカスタム COST: 200", 3}, {"近 アクア・ジム COST: 160", 2}, {"遠 量産型ガンタンク COST: 160", 2}, {"格 ガンキャノン重装型 COST: 160", 1}, {"近 ジム・コマンドライトアーマー COST: 160", 1}, {"射 ガンキャノン COST: 200", 1}, {"格 ボールK型 COST: 120", 0}, {"射 デザート・ジム COST: 160", 0}} set rRes to retRankingList(rList) of me –> {{rank:1, aCon:"近 装甲強化型ジム COST: 200", aTimes:60}, {rank:2, aCon:"遠 ジム・キャノン COST: 160", aTimes:39}, {rank:3, aCon:"近 ジム・コマンド COST: 200", aTimes:32}, {rank:4, aCon:"近 ジム(WD隊) COST: 160", aTimes:26}, {rank:5, aCon:"近 陸戦型ガンダム COST: 220", aTimes:23}, {rank:6, aCon:"近 ジム改 COST: 240", aTimes:22}, {rank:7, aCon:"遠 ガンタンク COST: 200", aTimes:21}, {rank:8, aCon:"格 ジム(指揮官機) COST: 160", aTimes:20}, {rank:9, aCon:"近 ジム COST: 120", aTimes:19}, {rank:10, aCon:"格 陸戦型ジム COST: 120", aTimes:10}, {rank:11, aCon:"近 ジム・トレーナー COST: 120", aTimes:9}, {rank:12, aCon:"射 ジム・スナイパーII(WD隊) COST: 220", aTimes:8}, {rank:13, aCon:"射 陸戦型ガンダム(ジム頭) COST: 200", aTimes:7}, {rank:14, aCon:"格 ガンダム COST: 280", aTimes:6}, {rank:14, aCon:"近 ザクII(F2) COST: 160", aTimes:6}, {rank:16, aCon:"格 ジム・ストライカー COST: 180", aTimes:4}, {rank:16, aCon:"近 ジム・寒冷地仕様 COST: 200", aTimes:4}, {rank:18, aCon:"狙 ジム・スナイパーカスタム COST: 200", aTimes:3}, {rank:19, aCon:"近 アクア・ジム COST: 160", aTimes:2}, {rank:19, aCon:"遠 量産型ガンタンク COST: 160", aTimes:2}, {rank:21, aCon:"格 ガンキャノン重装型 COST: 160", aTimes:1}, {rank:21, aCon:"近 ジム・コマンドライトアーマー COST: 160", aTimes:1}, {rank:21, aCon:"射 ガンキャノン COST: 200", aTimes:1}, {rank:24, aCon:"格 ボールK型 COST: 120", aTimes:0}, {rank:24, aCon:"射 デザート・ジム COST: 160", aTimes:0}} on retRankingList(rList) set aText to {} –出力用リスト set aCount to 0 set prevPoint to -1 set buffCount to 0 repeat with i in rList copy i to {j, bCount} if prevPoint = bCount then –同じポイントが続いた場合 if buffCount is not equal to 0 then –同じポイントが複数回(2回以上)続いている場合 set buffCount to buffCount + 1 log {"case A:", buffCount, aCount, bCount, prevPoint} else –同じポイントが続いている場合(2回目) set buffCount to 1 log {"case B:", buffCount, aCount, bCount, prevPoint} end if else –同じポイントが続いていない場合 if buffCount is not equal to 0 then –直前まで同じポイントが続いていた場合 set aCount to aCount + buffCount + 1 –バッファしておいたカウントを出力する set buffCount to 0 log {"case C:", buffCount, aCount, bCount, prevPoint} else –通常パターン(直前まで同じポイントが続いていたりしない) set buffCount to 0 set aCount to aCount + 1 –ランキング順位を+1 log {"case D:", buffCount, aCount, bCount, prevPoint} end if end if set the end of aText to {rank:aCount, aCon:j as string, aTimes:bCount} copy bCount to prevPoint end repeat return aText end retRankingList –リストを任意のデリミタ付きでテキストに on retArrowText(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 retArrowText |
AppleScript sorting performance comparison
Pure AppleScriptからAppleScriptObjCに部品を書き換えて、どの程度パフォーマンスが向上するかを調べてまとめてみました。グラフ内の単位は秒(seconds)です。
1D Array(list)では、Pure AppleScriptを使う意義はほとんど感じません。
2D Arrayで思ったよりもASOCが速いように見えませんが、Pure AppleScript側は指定できるキー数が1つのみのルーチンで、ASOC側は複数キーで個別にAscending/Descendingの指定ができるため、複数キー対応ソートルーチンで比較するべきなのかもしれません。
ただし、各GUIアプリケーションのオブジェクトはNSArrayに入れることはできないため、Pure AppleScript版の2D listのソーティングルーチンには利用価値があります。
今回のテストで予想外の結果が出たのがコレです。思ったよりもdictionary in array(record in list)のソートでパフォーマンス向上が見られない、といったところでしょうか。大量のデータをソートする場合に、dictionary in arrayよりも2D Arrayでデータを保持したほうが高速、ということは確実にいえるでしょう。
ファイルパスの階層とリストとの相互変換
AppleScript名:ファイルパスの階層とリストとの相互変換 |
— Created 2016-11-07 by Takaaki Naganoya — 2016 Piyomaru Software use AppleScript version "2.4" use scripting additions use framework "Foundation" set aStr to current application’s NSString’s stringWithString:"/Users/maro/Desktop/aTEST.scpt" set aList to aStr’s pathComponents() as list –> {"/", "Users", "maro", "Desktop", "aTEST.scpt"} set bList to {"/", "Users", "maro", "Desktop", "aTEST.scpt"} set bStr to (current application’s NSString’s pathWithComponents:bList) as string –> "/Users/maro/Desktop/aTEST.scpt" |