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 arrayWithObjects_(1, 2, 3) –> (NSArray) {1, 2, 3} –要素を順番に取得する set anEnum to anArray’s objectEnumerator() –> (__NSFastEnumerationEnumerator) <__NSFastEnumerationEnumerator: 0x6000002c1180> repeat set aValue to anEnum’s nextObject() if aValue = missing value then exit repeat log aValue end repeat |
タグ: 10.11savvy
配列の要素を逆順に取得する
Cocoaの機能を用いて1次元配列の内容を逆順にするAppleScriptです。
配列の内容を逆順にするのは、基本的なAppleScriptの機能でも「reverse of」で求められるので、わざわざCocoaの機能を利用するというのは相当に配列の要素数が多い(1万アイテム以上)場合に限られます(要素数が少ない場合だと、処理速度が遅くなるため)。
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 arrayWithObjects_(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 end repeat |
数値リストで指定数よりも大きな要素のみを抽出
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"} |
指定文字列ではじまる要素のみ抽出(ワイルドカード使用)
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"} |
指定リストから、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"} |
配列の要素を挿入する
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 arrayWithObjects_(1, 2, 3) –> (NSArray) {1, 2, 3} –要素を挿入する bArray’s insertObject:10 atIndex:1 bArray –> (NSArray) {1, 10, 2, 3, 100} |
配列の指定アイテムに指定要素を挿入
AppleScript名:配列の指定アイテムに指定要素を挿入 |
— Created 2017-10-29 by Takaaki Naganoya — 2017 Piyomaru Software use AppleScript version "2.4" use scripting additions use framework "Foundation" –Chapter 6 Lib.asobjcex3doc set theList to {5, 2, 9, 4, 2, 6, 3} set longList to my insertItem:99 atIndex:5 inList:theList –> {5, 2, 9, 4, 99, 2, 6, 3} set longList2 to insertItem of me at 99 for 5 from theList –> {5, 2, 9, 4, 99, 2, 6, 3} set longList3 to insetItemBy(99, 5, theList) of me –> {5, 2, 9, 4, 99, 2, 6, 3} –Objective-Cライクなパラメータ記述 on insertItem:anItem atIndex:(theIndex as integer) inList:(theList as list) set theArray to current application’s NSMutableArray’s arrayWithArray:theList theArray’s insertObject:anItem atIndex:(theIndex – 1) return theArray as list end insertItem:atIndex:inList: –無意味区による装飾 on insertItem at anItem for theIndex as integer from theList as list set aRes to my insertItem:anItem atIndex:theIndex inList:theList return aRes end insertItem –Pure AS風のパラメータ記述 on insetItemBy(anItem, theIndex, theList) set aRes to my insertItem:anItem atIndex:theIndex inList:theList return aRes end insetItemBy |
配列を逆順に(ASOC)
Cocoaの配列(NSArray)を逆順に並びかえるAppleScriptです。
普通のAppleScriptのlist型変数であれば、reverse ofで逆順に並び替えられますが、Cocoaの配列だとこんな感じです。
AppleScript名:配列を逆順に(ASOC) |
— Created 2017-07-30 by Takaaki Naganoya — 2017 Piyomaru Software use AppleScript version "2.4" use scripting additions use framework "Foundation" set aList to {1, 2, 3, 4, 5, 6} set anArray to current application’s NSMutableArray’s arrayWithArray:aList set revArray to (anArray’s reverseObjectEnumerator()’s allObjects()) as list –> {6, 5, 4, 3, 2, 1} |
1D Listの一部を取り出す
AppleScript名:1D Listの一部を取り出す |
— Created 2016-11-08 by Takaaki Naganoya — 2016 Piyomaru Software use AppleScript version "2.4" use scripting additions use framework "Foundation" set anArray to current application’s NSMutableArray’s arrayWithArray:{"1", "2", "3", "4", "5"} set anIndex to current application’s NSIndexSet’s indexSetWithIndexesInRange:(current application’s NSMakeRange(1, 3)) set cList to (anArray’s objectsAtIndexes:anIndex) as list –> {"2", "3", "4"} |
JTHistogramでArrayのヒストグラムを計算
AppleScript名:JTHistogramでArrayのヒストグラムを計算 |
— Created 2017-08-01 by Takaaki Naganoya — 2017 Piyomaru Software use AppleScript version "2.4" use scripting additions use framework "Foundation" use framework "JTHistogramKit" –https://github.com/Kinokoo/JTHistogram –http://piyocast.com/as/archives/4757 set anArray to current application’s NSMutableArray’s arrayWithArray:{1, 1, 1, 1, 1, 1, 2, 2, 3, 3, 3, 3} set histObj to current application’s JTHistogram’s alloc()’s initWithArray:anArray set histDict to histObj’s |histogram|() –> (NSDictionary) {0:0, 3:4, 2:2, 1:6} set relativeHistogramDict to histObj’s relativeHistogram() –> (NSDictionary) {0:0, 3:66.66667, 2:33.33334, 1:100} |
NSCountedSetでヒストグラムを計算2
AppleScript名:NSCountedSetでヒストグラムを計算2 |
— Created 2017-08-01 by Takaaki Naganoya — 2017 Piyomaru Software use AppleScript version "2.4" use scripting additions use framework "Foundation" use framework "ArrayRandomize" –https://github.com/masakihirokawa/objc-classes-dc-randomize set theList to (current application’s DCRandomize’s shuffle:1 max:9999) set theTime to current application’s NSDate’s |date|() set theCountedSet to current application’s NSCountedSet’s alloc()’s initWithArray:theList set newArray to current application’s NSMutableArray’s new() repeat with i from 1 to 10000 (newArray’s addObject:{theKey:i, theCount:(theCountedSet’s countForObject:i)}) end repeat theTime’s timeIntervalSinceNow() return newArray as list of string or string |
リストの連結(arrayByAddingObjectsFromArray)
AppleScript名:リストの連結(arrayByAddingObjectsFromArray) |
— Created 2017-10-10 by Takaaki Naganoya — 2017 Piyomaru Software use AppleScript version "2.4" use scripting additions use framework "Foundation" –http://piyocast.com/as/archives/4892 property NSMutableArray : a reference to current application’s NSMutableArray set anArray to NSMutableArray’s new() repeat 10000 times set anArray to anArray’s arrayByAddingObjectsFromArray:{1, 2, 3, 4, 5, 6, 7, 8, 9, 10} end repeat return (anArray as list) –> {1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10…….} –4.89sec |
リストの連結(addObjectsFromArray)
Cocoaの機能(NSMutableArray)を使って配列(AppleScriptではリスト)を連結するAppleScriptです。
普通にAppleScriptの配列型であるList型変数で配列同士の連結を行う場合には、
set aList to {1, 2, 3} set bList to {4, 5, 6} set cList to aList & bList --> {1, 2, 3, 4, 5, 6}
とします。
AppleScript自体に配列であるList型のデータを操作する機能がありますが、いわゆるメソッドと呼ばれるものがほとんどなく、AppleScript単体ではソートやデータ抽出などの機能もありません(ループでチェックしてソートしたり抽出することは可能。ユーザー同士で積み重ねてきた機能ルーチンの蓄積はけっこうあります)。
あるいは、外部のアプリケーション(FileMaker Pro)を利用したり、macOS標準搭載のDatabaseEventsなどを併用することでデータ抽出を行なってきたという歴史があります。
だいたいは、データ抽出のためにリストを全件ループでチェックして、条件に合うものを抽出するとか、そういう脳筋プログラミングをしてきました。アプリケーションのコントロールという超ハイレベルな操作を行う一方で、泥くさい地道なデータ処理能力が低かったので、おっそろしく地道なプログラムを作れる能力も求められてきた環境ともいえます。
macOS 10.10以降ではCocoaの機能が通常のAppleScriptでも利用できるようになったため、NSArray/NSMutableArrayの機能を用いてそれらのクラス由来のさまざまな機能が利用できるようになり、リストの連結についても、いったんNSMutableArrayに変換して各種機能を呼び出すことが行われるようになってきました。
ただし、リスト型変数をNSMutableArrayに変換するのにも時間はかかるため、巨大なデータ(数千〜1万項目以上)を扱うケースでなければAppleScriptだけで脳筋処理したほうが高速というケースはままあります。
本Scriptの末尾で連結したリストではなく、そのlengthを取得しているのは、連結したデータ項目数が多すぎて、そのままスクリプトエディタの「結果」欄に出力すると受信時間がかかりハングアップ状態に見えてしまうためです。
AppleScript名:リストの連結(addObjectsFromArray) |
— Created 2017-10-12 by Shane Stanley use AppleScript version "2.4" use scripting additions use framework "Foundation" property NSMutableArray : a reference to current application’s NSMutableArray set anArray to NSMutableArray’s new() repeat 10000 times anArray’s addObjectsFromArray:{1, 2, 3, 4, 5, 6, 7, 8, 9, 10} end repeat return length of (anArray as list) –> {1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 1…..} |
リストの連結(addObject)
AppleScript名:リストの連結(addObject) |
use AppleScript version "2.4" use scripting additions use framework "Foundation" set anArray to current application’s NSMutableArray’s new() anArray’s addObject:{1, 2, 3} anArray’s addObject:{4, 5, 6} anArray as list –> {{1, 2, 3}, {4, 5, 6}} |
2Dリスト内の要素のうち最多のアイテム数を求める
AppleScript名:2Dリスト内の要素のうち最多のアイテム数を求める |
— Created 2017-10-01 by Takaaki Naganoya — 2017 Piyomaru Software use AppleScript version "2.4" use scripting additions use framework "Foundation" set aList to {{1, 2, 3, 4, 5, 6, 4}, {1, 2, 3, 4, 5, 6}, {1, 2, 3, 4, 5, 6, 0, 0}} –7,6, 8 items set aRes to getMaxItemCountFrom2DArray(aList) of me –> 8 –max items is 8 on getMaxItemCountFrom2DArray(aList) set anArray to current application’s NSArray’s arrayWithArray:aList set eRes to (anArray’s valueForKeyPath:"@unionOfObjects.@count")’s valueForKeyPath:"@max.self" return eRes as integer end getMaxItemCountFrom2DArray |
2Dリストを左(counterclockwise)に90度回転
2D List(2次元配列)を左に90度回転させるAppleScriptです。
回転させるにあたって、各行のアイテム数のうち最大のものを求め、最大アイテム数に足りない行については詰め物をして、2次元配列をなるべく正方形ないし長方形に整った形にしてから回転させます。
AppleScript名:2Dリストを左(counterclockwise)に90度回転 |
— Created 2017-10-02 by Takaaki Naganoya — 2017 Piyomaru Software use AppleScript version "2.4" use scripting additions use framework "Foundation" property NSArray : a reference to current application’s NSArray set origList to {{1, 2, 3, 4, 5, 6, 7}, {11, 12, 13, 14, 15, 16}, {21, 22, 23, 24, 25, 26, 27, 28}} set wList to rotateListCounterClockwise90(origList, 0) of me –> {{0, 0, 28}, {7, 0, 27}, {6, 16, 26}, {5, 15, 25}, {4, 14, 24}, {3, 13, 23}, {2, 12, 22}, {1, 11, 21}} set sList to rotateListCounterClockwise90(wList, 0) of me –> {{28, 27, 26, 25, 24, 23, 22, 21}, {0, 0, 16, 15, 14, 13, 12, 11}, {0, 7, 6, 5, 4, 3, 2, 1}} set eList to rotateListCounterClockwise90(sList, 0) of me –> {{21, 11, 1}, {22, 12, 2}, {23, 13, 3}, {24, 14, 4}, {25, 15, 5}, {26, 16, 6}, {27, 0, 7}, {28, 0, 0}} set nList to rotateListCounterClockwise90(eList, 0) of me –> {{1, 2, 3, 4, 5, 6, 7, 0}, {11, 12, 13, 14, 15, 16, 0, 0}, {21, 22, 23, 24, 25, 26, 27, 28}} on rotateListCounterClockwise90(aList, blankItem) set curMax to 0 set curLen to length of aList set curMax to getMaxItemCountFrom2DArray(aList) of me set tmpList to {} set twoDList to make2DBlankArray(curLen, curMax) of me set curY to 1 repeat with x from curMax to 1 by -1 set curX to 1 repeat with y from 1 to curLen by 1 set aCon to getItemByXY(x, y, aList, blankItem) of me set twoDList to setItemByXY(curX, curY, twoDList, aCon) of me set curX to curX + 1 end repeat set curY to curY + 1 end repeat return twoDList end rotateListCounterClockwise90 on getMaxItemCountFrom2DArray(curList) set anArray to NSArray’s arrayWithArray:curList set eRes to (anArray’s valueForKeyPath:"@unionOfObjects.@count")’s valueForKeyPath:"@max.self" return eRes as integer end getMaxItemCountFrom2DArray –2D Listに配列の添字的なアクセスを行なってデータを取得 on getItemByXY(aX, aY, aList, aBlankItem) –1 based index try set aContents to contents of (item aX of item aY of aList) on error set aContents to aBlankItem end try return aContents end getItemByXY –2D Listに配列の添字的なアクセスを行なってデータを設定 on setItemByXY(aX, aY, tmpList, aContents) –1 based index set (item aX of item aY of tmpList) to aContents return tmpList end setItemByXY –空白の2D Array を出力する on make2DBlankArray(curLen, curMax) set outArray to {} repeat curMax times set tmpList to {} repeat curLen times set the end of tmpList to "" end repeat set the end of outArray to tmpList end repeat return outArray end make2DBlankArray |