Archive for the 'リスト処理(list)' Category

2017/04/17 リストをクラス名でフィルタする v0

リストをクラス名でフィルタするAppleScriptです。指定クラスに合致するデータをリスト中から抽出します。

Charanさんから先日掲載したリストに対して「もっと簡単に書けるよ」と指摘があって、試してみたらそのとおり! ひととおり動作確認して掲載しておくことにしました。

一応、対応OSを10.9からと記載してありますが、この内容だとおそらくもっと古いOSでも問題なく動作することでしょう。

as137.png
▲Classic Mac OS 8.6上のAppleScript J1-1.3.7で動作することを確認

AppleScript名:リストをクラス名でフィルタする v0
–http://piyocast.com/as/archives/4588

set theList to {1, 2, 2.0, “aaa”, “bbb”, {a:1}, {1, 3, 4, 5, 6}, false, true}

lists of theList
–>{{1, 3, 4, 5, 6}}
text of theList
–> {”aaa”, “bbb”}
strings of theList
–> {”aaa”, “bbb”}
–unicode texts of theList
–> error
records of theList
–> {{a:1}}
booleans of theList
–> {false, true}
reals of theList
–> {2.0}
integers of theList
–> {1, 2}
numbers of theList
–> {1, 2, 2.0}

★Click Here to Open This Script 

「integers」ということは「every integer」と書き換えることが可能なので、そのとおりに書き換えてみたら、予想通り動きました。

AppleScript名:リストをクラス名でフィルタする v0a
–http://piyocast.com/as/archives/4588

set theList to {1, 2, 2.0, "aaa", "bbb", {a:1}, {1, 3, 4, 5, 6}, false, true}

set bList to every integer of theList
–> {1, 2}
set cList to every real of theList
–> {2.0}
set dList to every string of theList
–> {"aaa", "bbb"}
set eList to every list of theList
–> {{1, 3, 4, 5, 6}}
set fList to every record of theList
–> {{a:1}}
set gList to every boolean of theList
–> {false, true}

★Click Here to Open This Script 

2017/04/15 リストをクラス名でフィルタする v2

リストをクラス名でフィルタするAppleScriptです。指定クラスに合致するデータをリスト中から抽出します。

修正:listに対して簡単に直接フィルターする方法については別途記述しておきます。本Scriptは他の用途に転用するような場合の記述例として掲載しておきます

NSArrayに入れてNSPredicateで抽出を行う方法があります。ただし、これだとクラス名がCocoaとAppleScriptで合わないので、いまひとつ使えません。

そこで、ひたすら原始的ではありますが、リストをループで回してクラス名を照合して別リストに追加、という処理を回してみました。超高級言語のAppleScriptですが、たまーにこういう泥くさいチェック処理を書く瞬間があります。

そのままだと知性のカケラもなんにもないので、せめてクラス名の同義語辞書を定義して、クラス名の表記ゆらぎ(というよりも、クラス間の内包関係。integerとrealはnumberに含まれるなど)に対応させてみました。

AppleScript名:リストをクラス名でフィルタする v2
– Created 2017-04-15 by Takaaki Naganoya
– 2017 Piyomaru Software
use AppleScript version “2.4″
use scripting additions
use framework “Foundation”

set aList to {1, “ABC”, 0.3, 5, {1, 2, 3}, {abc:“record”}, false}
set bList to filterListByClass(aList, “integer”)
–> {1, 5}
set cList to filterListByClass(aList, “number”)
–> {1, 0.3, 5}
set dList to filterListByClass(aList, “real”)
–> {0.3}
set eList to filterListByClass(aList, “string”)
–> {”ABC”}
set fList to filterListByClass(aList, “record”)
–> {{abc:”record”}}
set gList to filterListByClass(aList, “boolean”)
–> {false}

on filterListByClass(aList as list, aClass as string)
  set classNameList to getClassNameConsideringSynonyms(aClass) of me
  
  
set newList to {}
  
repeat with i in aList
    set j to contents of i
    
set myClass to (class of j) as string
    
if myClass is in classNameList then
      set the end of newList to j
    end if
  end repeat
  
return newList
end filterListByClass

on getClassNameConsideringSynonyms(aClassString)
  set smallClass to ((current application’s NSString’s stringWithString:aClassString)’s lowercaseString()) as string
  
set classRec to {|list|:{“list”}, |record|:{“record”}, |number|:{“number”, “integer”, “real”}, |integer|:{“integer”}, |real|:{“real”}, |text|:{“text”, “string”, “unicode text”}, |string|:{“text”, “string”, “unicode text”}, |unicode text|:{“text”, “string”, “unicode text”}, |boolean|:{“boolean”}}
  
set classDict to current application’s NSDictionary’s dictionaryWithDictionary:classRec
  
set aVal to (classDict’s valueForKey:smallClass) as list
  
if aVal = {missing value} then error “Unexpected class name string”
  
return aVal
end getClassNameConsideringSynonyms

★Click Here to Open This Script 

2017/04/11 NSMutableArrayの特定要素の書き換え

NSMutableArray中の特定要素を書き換えるAppleScriptです。

NSMutableArrayの内容をpredicateで条件を指定してフィルタリングする処理はAppleScriptでも頻繁に使うようになってきました。他のSQLデータベースに依存する必要もなく、処理速度も速いため非常に有効な手段です。

ただ、抽出処理は行えるものの、当該アイテムの書き換えを行って、もとのNSMutableArrayに書き戻せないとデータベース的な運用はできません。

そこで、簡単なサンプルScriptを作ってみて、Array中の特定要素を検索して書き換える処理を書いてみました。

AppleScript名:リスト中の指定アイテムを置き換える
– Created 2017-04-11 by Takaaki Naganoya
– 2017 Piyomaru Software
use AppleScript version “2.4″
use scripting additions
use framework “Foundation”
–http://piyocast.com/as/archives/4579

set anArray to current application’s NSMutableArray’s arrayWithArray:{5, 2, 1, 3, 4}
anArray’s replaceObjectsAtIndexes:(current application’s NSIndexSet’s indexSetWithIndex:0) withObjects:{-1}
return anArray as list
–> {-1, 2, 1, 3, 4}

★Click Here to Open This Script 

AppleScript名:レコード入りリスト中の指定アイテムを置き換える
– Created 2017-04-11 by Takaaki Naganoya
– 2017 Piyomaru Software
use AppleScript version “2.4″
use scripting additions
use framework “Foundation”
–http://piyocast.com/as/archives/4579

set anArray to current application’s NSMutableArray’s arrayWithArray:{{aLabel:0, bLabel:2, cLabel:100}, {aLabel:2, bLabel:3, cLabel:1}}
anArray’s replaceObjectsAtIndexes:(current application’s NSIndexSet’s indexSetWithIndex:0) withObjects:{{aLabel:-1, bLabel:-2, cLabel:-3}}
return anArray as list
–>  {{cLabel:-3, aLabel:-1, bLabel:-2}, {cLabel:1, aLabel:2, bLabel:3}}

★Click Here to Open This Script 

AppleScript名:リスト中の指定アイテムを置き換える(登場アイテム番号自動検索)
– Created 2017-04-11 by Takaaki Naganoya
– 2017 Piyomaru Software
use AppleScript version “2.4″
use scripting additions
use framework “Foundation”
–http://piyocast.com/as/archives/4579

set aTargValue to 2
set aNewValue to -100
set anArray to current application’s NSMutableArray’s arrayWithArray:{5, 2, 1, 3, 4}
set aInd to anArray’s indexOfObject:aTargValue
anArray’s replaceObjectsAtIndexes:(current application’s NSIndexSet’s indexSetWithIndex:aInd) withObjects:{aNewValue}
return anArray as list
–>  {5, -100, 1, 3, 4}

★Click Here to Open This Script 

AppleScript名:レコード入りリスト中の指定アイテムを置き換える(登場アイテム番号自動検索)
– Created 2017-04-11 by Takaaki Naganoya
– 2017 Piyomaru Software
use AppleScript version “2.4″
use scripting additions
use framework “Foundation”
–http://piyocast.com/as/archives/4579

set aTargValue to {aLabel:2, bLabel:3, cLabel:1}
set aNewValue to {aLabel:-1, bLabel:-2, cLabel:-3}

set anArray to current application’s NSMutableArray’s arrayWithArray:{{aLabel:0, bLabel:2, cLabel:100}, {aLabel:2, bLabel:3, cLabel:1}, {aLabel:0, bLabel:0, cLabel:0}}
set aInd to anArray’s indexOfObject:aTargValue

anArray’s replaceObjectsAtIndexes:(current application’s NSIndexSet’s indexSetWithIndex:aInd) withObjects:{aNewValue}
return anArray as list
–>  {{cLabel:100, aLabel:0, bLabel:2}, {cLabel:-3, aLabel:-1, bLabel:-2}, {cLabel:0, aLabel:0, bLabel:0}}

★Click Here to Open This Script 

2017/03/18 文字を集合(CountedSet)に変換して文字列同士の近似度を計算する v2

複数の文字列同士の近似度を擬似的に計算できないかと考えて、文字列をCountedSetに変換して、CountedSet同士でand演算(intersectSet)を実行。その計算結果が大きいほど「文字列中に含まれている文字列の傾向が似ている」と判断するテストのAppleScriptです。

countedset_intersect_resized.png

とりあえずはintersectSetで積集合を計算しています。重複している部分を求めているわけです。

 「This is an apple.」と「This is a pinapple.」–> 11
 「This is a pinapple.」と「Piyomaru San Dayo.」–> 5
 「Piyomaru San Dayo.」と「This is an apple.」–> 5

v1とv2の計算結果を合わせて、両方の傾向を反映させるようにするとよいのかもしれません。

AppleScript名:文字を集合(CountedSet)に変換して文字列同士の近似度を計算する v2
– Created 2017-03-18 by Takaaki Naganoya
– 2017 Piyomaru Software
use AppleScript version "2.4"
use scripting additions
use framework "Foundation"
–http://piyocast.com/as/archives/4532

set aStr to "This is a pinnapple."
set bStr to "This is an apple."
set cStr to "Piyomaru San Dayo."

set a1Res to getApproximationBetweenStringsIntersect(aStr, bStr) of me
–>  11

set bRes to getApproximationBetweenStringsIntersect(bStr, cStr) of me
–>  5

set cRes to getApproximationBetweenStringsIntersect(cStr, aStr) of me
–>  5

on getApproximationBetweenStringsIntersect(aStr, bStr)
  set aList to current application’s NSMutableArray’s arrayWithArray:(characters of aStr)
  
set bList to current application’s NSMutableArray’s arrayWithArray:(characters of bStr)
  
  
set aIndex to current application’s NSCountedSet’s alloc()’s initWithArray:aList
  
set bIndex to current application’s NSCountedSet’s alloc()’s initWithArray:bList
  
  
aIndex’s intersectSet:bIndex
  
set aRes to aIndex’s allObjects()’s |count|()
  
return aRes
end getApproximationBetweenStringsIntersect

★Click Here to Open This Script 

2017/03/18 文字を集合(CountedSet)に変換して文字列同士の近似度を計算する v1

複数の文字列同士の近似度を擬似的に計算できないかと考えて、文字列をCountedSetに変換して、CountedSet同士で減算を実行。その計算結果が少ないほど「文字列中に含まれている文字列の傾向が似ている」と判断するテストのAppleScriptです。

countedset.png

とりあえずはminusSetで減算を行なっていますが、ほかの方法も試してみたいところです。

本Scriptでは、得られた結果の数値が小さければ重複している文字が多いということで、計算結果そのものにはあまり意味はありませんが、複数の結果を大小比較して、数値が小さいもののペアが「似たような傾向を持つもの」として期待できます。

 「This is an apple.」と「This is a pinapple.」–> 3
 「This is a pinapple.」と「Piyomaru San Dayo.」–> 8
 「Piyomaru San Dayo.」と「This is an apple.」–> 9

ということで、これらの間では「This is an apple.」と「This is a pinapple.」の近似度が一番高いといえることになります。

AppleScript名:文字を集合(CountedSet)に変換して文字列同士の近似度を計算する v1
– Created 2017-03-18 by Takaaki Naganoya
– 2017 Piyomaru Software
use AppleScript version “2.4″
use scripting additions
use framework “Foundation”
–http://piyocast.com/as/archives/4530

set aStr to “This is a pinnapple.”
set bStr to “This is an apple.”
set cStr to “Piyomaru San Dayo.”

set a1Res to getApproximationBetweenStrings(aStr, bStr) of me
–>  3

set bRes to getApproximationBetweenStrings(bStr, cStr) of me
–>  8

set cRes to getApproximationBetweenStrings(cStr, aStr) of me
–>  9

on getApproximationBetweenStrings(aStr, bStr)
  set aList to current application’s NSMutableArray’s arrayWithArray:(characters of aStr)
  
set bList to current application’s NSMutableArray’s arrayWithArray:(characters of bStr)
  
  
set aIndex to current application’s NSCountedSet’s alloc()’s initWithArray:aList
  
set bIndex to current application’s NSCountedSet’s alloc()’s initWithArray:bList
  
  
aIndex’s minusSet:bIndex
  
set aRes to aIndex’s allObjects()’s |count|()
  
  
bIndex’s minusSet:aIndex
  
set bRes to bIndex’s allObjects()’s |count|()
  
  
if aRes bRes then
    return bRes
  else
    return aRes
  end if
end getApproximationBetweenStrings

★Click Here to Open This Script 

2017/03/07 矩形座標同士の合計

NSUnionRectによる矩形座標(NSRect)の合計をためしてみました。

unionrect.png

実際に方眼紙を塗りつぶしてみると、計算結果が不思議な感じもするのですが(空いているセルもあるので)、、、そういうものなんでしょう、、、か(^ー^;;;;;

AppleScript名:矩形座標同士の合計
– Created 2017-03-06 by Takaaki Naganoya
– 2017 Piyomaru Software
use AppleScript version “2.4″
use scripting additions
use framework “Foundation”
–http://piyocast.com/as/archives/4515

set a1Rect to {origin:{x:10, y:10}, |size|:{width:40, height:40}}
set b1Rect to {origin:{x:30, y:30}, |size|:{width:40, height:40}}
set a1Res to current application’s NSUnionRect(a1Rect, b1Rect)
–>  {origin:{x:10.0, y:10.0}, size:{width:60.0, height:60.0}}

★Click Here to Open This Script 

2017/03/01 NSSet/NSMutableSetの演算 2

NSSet/NSMutableSetの演算について、Shane Stanleyから「こっちのほうが短く書けるぞ」というツッコミが(Thanks!)。

set1.png

AppleScript名:補集合(set difference)v2
– Created 2017-02-24 by Takaaki Naganoya
– Created 2017-03-01 by Shane Stanley
use AppleScript version "2.4"
use scripting additions
use framework "Foundation"
–http://piyocast.com/as/archives/4491

set aSet to current application’s NSMutableSet’s setWithArray:{1, 2, 3, 4}
set bSet to current application’s NSMutableSet’s setWithArray:{3, 5, 6, 7}

aSet’s minusSet:bSet –補集合
aSet’s allObjects() as list
–>  {2, 1, 4}

★Click Here to Open This Script 

set2.png

AppleScript名:積集合(product)v2
– Created 2017-02-24 by Takaaki Naganoya
– Created 2017-03-01 by Shane Stanley
use AppleScript version "2.4"
use scripting additions
use framework "Foundation"
–http://piyocast.com/as/archives/4491

set aSet to current application’s NSMutableSet’s setWithArray:{1, 2, 3, 4}
set bSet to current application’s NSMutableSet’s setWithArray:{3, 5, 6, 7}

aSet’s intersectSet:bSet –積集合
aSet’s allObjects() as list
–>  {3}

★Click Here to Open This Script 

set3.png

AppleScript名:和集合(union)v2
– Created 2017-02-24 by Takaaki Naganoya
– Created 2017-03-01 by Shane Stanley
use AppleScript version "2.4"
use scripting additions
use framework "Foundation"
–http://piyocast.com/as/archives/4491

set aSet to current application’s NSMutableSet’s setWithArray:{1, 2, 3, 4}
set bSet to current application’s NSMutableSet’s setWithArray:{3, 5, 6, 7}

aSet’s unionSet:bSet –和集合
aSet’s allObjects() as list
–>  {5, 1, 6, 2, 7, 3, 4}

★Click Here to Open This Script 

2017/03/01 NSSet/NSMutableSetの演算

NSSet/NSMutableSetが集合を表すClassであることをあとから知り、集合同士の演算の例を調べてみました。こういう地道な調査があとでジワジワ効いてくるのです。

set1.png

AppleScript名:補集合(set difference)
– Created 2017-02-24 by Takaaki Naganoya
– 2017 Piyomaru Software
use AppleScript version “2.4″
use scripting additions
use framework “Foundation”
–http://piyocast.com/as/archives/4487

set aArray to current application’s NSArray’s arrayWithArray:{1, 2, 3, 4}
set bArray to current application’s NSArray’s arrayWithArray:{3, 5, 6, 7}

set aSet to current application’s NSMutableSet’s alloc()’s initWithArray:aArray
set bSet to current application’s NSMutableSet’s alloc()’s initWithArray:bArray

aSet’s minusSet:bSet –補集合
aSet’s allObjects() as list
–>  {2, 1, 4}

★Click Here to Open This Script 

set2.png

AppleScript名:積集合(product)
– Created 2017-02-24 by Takaaki Naganoya
– 2017 Piyomaru Software
use AppleScript version “2.4″
use scripting additions
use framework “Foundation”
–http://piyocast.com/as/archives/4487

set aArray to current application’s NSArray’s arrayWithArray:{1, 2, 3, 4}
set bArray to current application’s NSArray’s arrayWithArray:{3, 5, 6, 7}

set aSet to current application’s NSMutableSet’s alloc()’s initWithArray:aArray
set bSet to current application’s NSMutableSet’s alloc()’s initWithArray:bArray

aSet’s intersectSet:bSet –積集合
aSet’s allObjects() as list
–>  {3}

★Click Here to Open This Script 

set3.png

AppleScript名:和集合(union)
– Created 2017-02-24 by Takaaki Naganoya
– 2017 Piyomaru Software
use AppleScript version “2.4″
use scripting additions
use framework “Foundation”
–http://piyocast.com/as/archives/4487

set aArray to current application’s NSArray’s arrayWithArray:{1, 2, 3, 4}
set bArray to current application’s NSArray’s arrayWithArray:{3, 5, 6, 7}

set aSet to current application’s NSMutableSet’s alloc()’s initWithArray:aArray
set bSet to current application’s NSMutableSet’s alloc()’s initWithArray:bArray

aSet’s unionSet:bSet –和集合
aSet’s allObjects() as list
–>  {5, 1, 6, 2, 7, 3, 4}

★Click Here to Open This Script 

2017/02/23 リストから重複要素のみを返す v2

Shane Stanleyによる「リストから重複する要素のみを抽出して返すAppleScript」の改良版です。シンプルで美しい処理になっています。

この手の処理でNSSetやNSCountedSetを使うのは「そういうものだろー」とすぐに思いつきますが、「minusSet:」というのはドキュメント中から見つけ切れませんでした。これは深い(^ー^;;。

また、ループ処理や条件判断の処理が入っていないため、自分の書いたバージョンよりも2.3倍ぐらい高速でした(100回実行時の平均)。

AppleScript名:リストから重複要素のみを返す v2
– Created 2017-02-23 by Shane Stanley
use AppleScript version “2.4″
use scripting additions
use framework “Foundation”
–http://piyocast.com/as/archives/4469

set aList to {“4efa7f9f587f3d1dbc4a1f6ebff92ef5″, “59cd07ea69acc2c9004dc815803cf184″, “5841f4bcc13e85c3b8ba1eafcacd43be”, “dfb393cd3c0eb3f228236367f171cd01″, “59cd07ea69acc2c9004dc815803cf184″, “59cd07ea69acc2c9004dc815803cf184″}
set dList to returnDuplicatesOnly(aList) of me
–> {”59cd07ea69acc2c9004dc815803cf184″}

on returnDuplicatesOnly(aList)
  set countedSet to current application’s NSCountedSet’s alloc()’s initWithArray:aList
  
set simpleSet to current application’s NSSet’s setWithArray:aList
  
countedSet’s minusSet:simpleSet
  
return countedSet’s allObjects() as list
end returnDuplicatesOnly

★Click Here to Open This Script 

2017/02/16 YAMLのじっけん

オープンソースのフレームワーク「YAML.framework」(Mirek Rusin)を用いて、構造化データ記述言語であるYAMLとオブジェクト(listやrecord)との間の相互変換を行うAppleScriptです。

これまでYAMLとは縁のない生活を送ってきましたが、とくに問題はありませんでした。構造を持つデータの分量が増えた場合には、プログラム中に直接記述せず、Excelの表からデータを読み取って処理したり、データベースなど他のデータソースからデータを取得していました。

ただ、listとかrecordの内容が込み入ってくる(フィールド数が多いとか、入れ子構造の段数が深いとか)と、こういう仕組みがあったほうが便利なんだろうな、ということは理解できます。

YAML.frameworkのプロジェクトをXcodeでビルドし、出来上がったフレームワークを~/Library/Frameworksに入れてテストしてみてください。

途中、Githubに掲載されているObjective-CのサンプルプログラムがNSInputStreamを使っており、これをAppleScriptに書き換えて呼び出すとAppleScriptの処理系が100%クラッシュ。NSDataを経由して変換する方法なども試してみましたがNSInputStreamを作りにいくとクラッシュ。

結局、Stringから直接変換するメソッドがあったため、これを使用することで安定して処理できるようになりました。

当初は機械学習フレームワークの「YCML」をいじくっていたのですが、その過程で本フレームワークを発見。なかなか有用性が高そうなので試してみた次第です。

AppleScript名:YAMLのじっけん
– Created 2017-02-16 by Takaaki Naganoya
– 2017 Piyomaru Software
use AppleScript version “2.4″
use scripting additions
use framework “Foundation”
use framework “YAML” –https://github.com/mirek/YAML.framework
–http://piyocast.com/as/archives/4464

–YAMLの文字列からオブジェクトを生成する
set aYAMLstr to
items:
- name: Foo
- name: Bar

set aStr to current application’s NSString’s stringWithString:aYAMLstr
set aData to aStr’s dataUsingEncoding:(current application’s NSUTF8StringEncoding)

set aData to current application’s YAMLSerialization’s objectsWithYAMLString:aStr options:(4096) |error|:(missing value)
–>  (NSArray) {{items:{{name:”Foo”}, {name:”Bar”}}}}

–オブジェクトからYAMLの文字列を取得する
set aString to (current application’s YAMLSerialization’s createYAMLStringWithObject:aData options:(1) |error|:(missing value)) as string
(* –>
“—
- items:
- name: Foo
- name: Bar
…”
*)

★Click Here to Open This Script 

AppleScript名:YAMLのじっけん4
– Created 2017-02-16 by Takaaki Naganoya
– 2017 Piyomaru Software
use AppleScript version “2.4″
use scripting additions
use framework “Foundation”
use framework “YAML” –https://github.com/mirek/YAML.framework
–http://piyocast.com/as/archives/4464

–YAMLの文字列からオブジェクトを生成する
set aYAMLstr to
- name: Smith
email: smith@mail.com
- name: Shelton
email: shelton@mail.com
- name: Kelly
email: kelly@mail.com

set aRes to retObjectFromYAMLString(aYAMLstr) of me
–>  {{{name:”Smith”, email:”smith@mail.com”}, {name:”Shelton”, email:”shelton@mail.com”}, {name:”Kelly”, email:”kelly@mail.com”}}}

set bYAMLstr to
names: [Smith, Shelton, Kelly]
emails: [smith@mail.com, shelton@mail.com, kelly@mail.com]

set bRes to retObjectFromYAMLString(bYAMLstr) of me
–>  {{names:{”Smith”, “Shelton”, “Kelly”}, emails:{”smith@mail.com”, “shelton@mail.com”, “kelly@mail.com”}}}

–オブジェクト(list)からYAMLの文字列を生成する
set bStr to retYAMLStringFromObject(bRes)
(*  
“—
- names:
- Smith
- Shelton
- Kelly
emails:
- smith@mail.com
- shelton@mail.com
- kelly@mail.com


*)

on retObjectFromYAMLString(aYAMLstr as string)
  set aStr to current application’s NSString’s stringWithString:aYAMLstr
  
set aData to aStr’s dataUsingEncoding:(current application’s NSUTF8StringEncoding)
  
set aData to current application’s YAMLSerialization’s objectsWithYAMLString:aStr options:(4096) |error|:(missing value)
  
return aData as list
end retObjectFromYAMLString

on retYAMLStringFromObject(anObject)
  set aString to (current application’s YAMLSerialization’s createYAMLStringWithObject:anObject options:(1) |error|:(missing value)) as string
  
return aString
end retYAMLStringFromObject

★Click Here to Open This Script 

2016/12/15 PDFしおり用データをNumbersから取得

PDFに「しおり」を作成する元のデータをNumbers上に記述しておくと、作成用のデータを取得・変換するAppleScriptです。構文確認および実行には、Shane Stanleyの「BridgePlus」AppleScript Libraries(フリー)のインストールを必要とします。

また、Numbersで(↓)のような書類を作成して、Numbersでオープンしていることが動作の前提条件です。

numbers_shiori.png

元のプログラムでは直接Script Editor上でレコードとして記述するのが、なかなか大変。また、親項目をタイトル文字列で記述するのも(作業時にミスりそうで)大変だったので、Numbers書類上で記述できるようにしてみたものです。

shiori.png

親項目は番号で記述するようにして、ID自体の連番の生成もAppleScriptから行い、極力作業ミスが発生しないように配慮してみました。

shiori2.png

AppleScript名:しおり用データをNumbersから取得
【コメント】 Book2_index_v2 を前提としています
– Created 2016-12-15 by Takaaki Naganoya
– 2016 Piyomaru Software
use AppleScript version “2.4″
use framework “Foundation”
use scripting additions
use BridgePlus : script “BridgePlus”
–http://piyocast.com/as/archives/4363

set aData to getIndexRecListFromNumbers() of me
–> {{|index|:3, title:”広告”, |parent|:”"}, {|index|:4, title:”本書購入特典のご案内”, |parent|:”"},…..

–NumbersのデータからPDFに付けるしおりのデータを取得する
on getIndexRecListFromNumbers()
  tell application “Numbers”
    tell window 1
      set aWinProp to properties
    end tell
    
    
set aDoc to document of aWinProp
    
tell aDoc
      tell active sheet
        tell table 1
          set colNum to column count
          
if colNum is not equal to 4 then error “Illegal Column Numbers”
          
set rowNum to row count
          
set vList to value of every cell
        end tell
      end tell
    end tell
  end tell
  
  
–Transform 1D array to 2D array
  
load framework
  
set tdList to (current application’s SMSForder’s subarraysFrom:(vList) groupedBy:colNum |error|:(missing value)) as list
  
–> {{”ID”, “index”, “title”, “parent”}, {1.0, 3.0, “広告”, missing value}, …..
  
  
–Skip First Row
  
set td2List to rest of tdList –first itemだけスキップする
  
  
set mokujiRecords to {}
  
repeat with i in td2List
    copy i to {anID, anIND, aTITLE, aParent}
    
    
–log {anID, anIND, aTITLE, aParent}
    
if aParent is not equal to missing value then
      set bParent to contents of item 3 of (item aParent of td2List)
    else
      set bParent to “”
    end if
    
    
set tmpRec to {|index|:(contents of anIND) as integer, title:aTITLE, |parent|:bParent}
    
set the end of mokujiRecords to tmpRec
  end repeat
  
  
return mokujiRecords
  
end getIndexRecListFromNumbers

★Click Here to Open This Script 

2016/12/14 &と=で区切られたテキストをrecordに 改

「aParam=1234&bParam=2345」のように、URLのパラメータ部のような文字列を「&」と「=」で区切ってrecordとして出力するAppleScriptです。

「&と=で区切られたテキストをrecordに(NSScanner版)」をedama2さんがさらに改良したものです。

「先日掲載されたNSScannerのスクリプト、自分でも試してみてとても便利だったんですが、値なしの時にエラーになるので修正してみました。

あとリファレンス本に「repeat until」はあんまり使わないと書いてあったので使ってみました。(edama2さん)」

なるほど。たしかにラベルだけで値が存在しないケースに対応できるとよさそうです。

AppleScript名:&と=で区切られたテキストをrecordに 改
– Created 2016-12-12 by Shane Stanley
– Modified 2016-12-14 by edama2
use AppleScript version "2.4"
use scripting additions
use framework "Foundation"
–http://piyocast.com/as/archives/4358

set aParamStr to "access_token=XXxxx(XXxXXXXXxxXxxXXx))&expires=86399&name="
set aDict to (parseStrByAmpAndEqual(aParamStr) of me)
–>  {expires:"86399", |name|:"", access_token:"XXxxx(XXxXXXXXxxXxxXXx))"}

on parseStrByAmpAndEqual(aParamStr)
  set theScanner to current application’s NSScanner’s scannerWithString:aParamStr
  
set aDict to current application’s NSMutableDictionary’s |dictionary|()
  
  
repeat until (theScanner’s isAtEnd as boolean)
    – terminate check, return the result (aDict) to caller
    
set {theResult, theKey} to theScanner’s scanUpToString:"=" intoString:(reference)
    
    
– skip over separator
    
theScanner’s scanString:"=" intoString:(missing value)
    
set {theResult, theValue} to theScanner’s scanUpToString:"&" intoString:(reference)
    
if theValue is missing value then set theValue to "" –>追加
    
    
– skip over separator
    
theScanner’s scanString:"&" intoString:(missing value)
    
    
aDict’s setObject:theValue forKey:theKey
  end repeat
  
  
return aDict as record
end parseStrByAmpAndEqual

★Click Here to Open This Script 

2016/12/13 顔認識結果のデータを加工

Microsoftの顔認識APIを呼び出して、その結果を加工して表情認識APIを呼び出すために、顔認識APIの実行結果を加工するAppleScriptです。

まだ表情認識APIは呼び出せていませんが、その途中で作ったものです。

典型的なデータ加工の処理なので、ほかにも(もう少しうまい)やり方がありそうです。

AppleScript名:顔認識結果のデータを加工
– Created 2016-12-13 by Takaaki Naganoya
– 2016 Piyomaru Software
use AppleScript version "2.4"
use scripting additions
use framework "Foundation"
–http://piyocast.com/as/archives/4357

set aList to current application’s NSArray’s arrayWithArray:{{faceId:"c49883a0-c4ee-4671-ad06-6f7f8370ab20", faceRectangle:{top:68, width:40, |left|:336, height:40}}, {faceId:"93459b48-4c19-4cc7-85e6-b38b8d0fc73b", faceRectangle:{top:81, width:38, |left|:92, height:38}}, {faceId:"9c796619-c654-47dd-b7b0-c382dc6bda84", faceRectangle:{top:63, width:38, |left|:214, height:38}}, {faceId:"94a2ceec-c089-494c-982e-a213579342b6", faceRectangle:{top:92, width:38, |left|:462, height:38}}, {faceId:"18e8dad0-fe46-4c5c-81c3-3ba483129512", faceRectangle:{top:89, width:37, |left|:700, height:37}}, {faceId:"4031f4bd-4e47-4050-89a0-f66e2e4e9142", faceRectangle:{top:45, width:37, |left|:570, height:37}}}

set aRes to retFaceArray(aList) of me
–>  "336,68,40,40;92,81,38,38;214,63,38,38;462,92,38,38;700,89,37,37;570,45,37,37"

on retFaceArray(aList)
  set a1Res to (aList’s valueForKeyPath:"faceRectangle.top") as list
  
set a2Res to (aList’s valueForKeyPath:"faceRectangle.width") as list
  
set a3Res to (aList’s valueForKeyPath:"faceRectangle.left") as list
  
set a4Res to (aList’s valueForKeyPath:"faceRectangle.height") as list
  
  
set aLen to length of a1Res
  
set aRes to {}
  
  
repeat with i from 1 to aLen
    set aLeft to (contents of item i of a3Res) as string
    
set aTop to (contents of item i of a1Res) as string
    
set aWidth to (contents of item i of a2Res) as string
    
set aHeight to (contents of item i of a4Res) as string
    
set tmpRes to aLeft & "," & aTop & "," & aWidth & "," & aHeight
    
set the end of aRes to tmpRes
  end repeat
  
  
set allRes to retStrFromArrayWithDelimiter(aRes, ";") of me
  
  
return allRes
end retFaceArray

–リストを指定デリミタをはさんでテキスト化
on retStrFromArrayWithDelimiter(aList, aDelim)
  set anArray to current application’s NSArray’s arrayWithArray:aList
  
set aRes to anArray’s componentsJoinedByString:aDelim
  
return aRes as text
end retStrFromArrayWithDelimiter

★Click Here to Open This Script 

2016/12/08 GameplayKitを使ったリストのシャッフル

Shane Stanleyから教えてもらった、GameplayKitを用いた高速なリストのシャッフルScriptです。ただし、実行にはmacOS 10.12を必要とします。

9999項目のリストをシャッフルする処理で、DCRandomizeを使ったScriptで0.02秒、本Script(GameplayKitのshuffledArray())では0.427秒かかりました(10回実行時の平均値)。

本Scriptでも9999項目のNSMutableArrayの作成部分だけ取り出して計測すると0.405秒かかっているので、シャッフル部分は0.02秒程度です。

AppleScript名:GameplayKitを使ったリストのシャッフル
– Created 2016-12-08 by Shane Stanley
use AppleScript version “2.5″
use framework “Foundation”
use framework “GameplayKit”
use scripting additions
–http://piyocast.com/as/archives/4353

set anArray to current application’s NSArray’s arrayWithArray:{1, 2, 3, 4, 5, 6, 7, 8, 9, 10}
set newArray to anArray’s shuffledArray() as list – requires macOS 10.12

★Click Here to Open This Script 

AppleScript名:GameplayKitを使ったリストのシャッフル(計測用)
– Created 2016-12-08 by Shane Stanley
– Modified 2016-12-08 by Takaaki Naganoya
use AppleScript version “2.5″
use framework “Foundation”
use framework “GameplayKit”
use scripting additions
–http://piyocast.com/as/archives/4353

set anArray to current application’s NSMutableArray’s alloc()’s init()
repeat with i from 1 to 10000
  (anArray’s addObject:i)
end repeat

set newArray to anArray’s shuffledArray() as list – requires macOS 10.12

★Click Here to Open This Script 

AppleScript名:リストのシャッフル(計測用)
– Created 2016-12-06 by Takaaki Naganoya
– 2016 Piyomaru Software
use AppleScript version “2.4″
use scripting additions
use framework “Foundation”
use framework “ArrayRandomize” –https://github.com/masakihirokawa/objc-classes-dc-randomize
–http://piyocast.com/as/archives/4353

–1〜9999の数値をシャッフルして配列取得
set cArray to (current application’s DCRandomize’s shuffle:1 max:9999) as list

★Click Here to Open This Script 

2016/12/07 リスト項目のシャッフル(ASOC)

リスト項目のシャッフルを行うAppleScriptです。オープンソースの「objc-classes-dc-randomize」をフレームワーク化した「ArrayRandomize」フレームワークを呼び出してシャッフルしています。

AppleScriptだけで作成した9999項目のリストのシャッフルと比べて、5,000倍ぐらい高速です(Objective-C側で処理した内容をただlistに変換しているだけなので)。本フレームワークを使うと、9999項目のリストのシャッフル生成で0.018秒(MacBook Pro Retina 2012 Core i7 2.66GHz)でした。

# ただ、比較対象のPure AppleScriptのプログラムも、まだまだ高速化の余地があったので、実際にはもう少し(10%ぐらい?)差は小さいと思います。Pure AppleScriptでも1,000項目ぐらいだと1秒ぐらいで処理が終わるのですが、、、ただ乱数を配列に追加するだけでなく、存在チェックと乱数の再生成を行うので、なかなかASには負荷が高い処理です

ArrayRandomize.frameworkをmacOS 10.10以降用にビルドしたバイナリを用意しましたので、自己責任で~/Library/Frameworksフォルダに入れて使って使ってみてください。

→ フレームワーク(19KB)のダウンロード

AppleScript名:リスト項目のシャッフル(ASOC)
– Created 2016-12-06 by Takaaki Naganoya
– 2016 Piyomaru Software
use AppleScript version “2.4″
use scripting additions
use framework “Foundation”
use framework “ArrayRandomize” –https://github.com/masakihirokawa/objc-classes-dc-randomize
–http://piyocast.com/as/archives/4351

–配列をシャッフルして取得
set anArray to current application’s NSMutableArray’s alloc()’s initWithArray:{1, 2, 3, 4, 5}
set bArray to (current application’s DCRandomize’s shuffleArray:anArray) as list
–>  {5, 3, 1, 2, 4}

–1〜10の数値をシャッフルして配列取得
set cArray to (current application’s DCRandomize’s shuffle:1 max:10) as list
–>  {9, 4, 6, 5, 3, 2, 7, 8, 1, 10}

–5〜10の範囲の乱数を取得
set dArray to (current application’s DCRandomize’s range:5 max:10) as integer
–>  7

–5〜10の範囲で 9以外の乱数を取得
set eArray to (current application’s DCRandomize’s exact:5 max:10 exceptId:9)
–>  9

★Click Here to Open This Script 

2016/11/05 XMLをNSDictionaryに

オープンソースのXMLDictionary(By Nick Lockwood)をFramework化した「XmlToDictKit」を呼び出して、XMLをNSDictionaryにするAppleScriptです。

XMLをNSDictionaryにするのには、なかなか手こずらされており、依然としてSatimageのXMLLib OSAXが手放せない状況ですが、OSAXを使わずになんとかする方法についてはつねに模索しておりました。

「XML Parser」などをキーワードにGithub上でいろいろ物色していたところ、そんなに気合の入ったキーワードでなくても、「XML NSDictionary」ぐらいでいろいろ見つかりました。

それらを人気順でソートし上から順番に物色。条件が合って手軽にフレームワーク化に成功したのがこの「XMLDictionary」です。

XMLをNSDictionaryに変換し、さらにNSDictionaryをrecordまで変換すればAppleScriptで簡単に取り扱えます(NSDictionaryの属性値ラベルに空白などが入っていなければ)。

フレームワークについては、例によってOS X 10.10をターゲットにしてビルドしてみました。~/Library/Frameworksに入れてご利用ください(あくまで自己責任で)。

XMLそのものよりも、RSSのParseが割と手間だったので、RSSを手軽に扱えるようになったことのメリットが大きいと感じています。

→ FrameworkのZipアーカイブのダウンロード(30KB)

AppleScript名:XMLをDictionaryに(remote file)
– Created 2016-11-05 by Takaaki Naganoya
– 2016 Piyomaru Software
use AppleScript version “2.4″
use scripting additions
use framework “Foundation”
use framework “XmlToDictKit” –https://github.com/nicklockwood/XMLDictionary
–http://piyocast.com/as/archives/4304

set aURL to current application’s |NSURL|’s alloc()’s initWithString:“http://www.ibiblio.org/xml/examples/shakespeare/all_well.xml”
set xmlString to current application’s NSString’s alloc()’s initWithContentsOfURL:aURL encoding:(current application’s NSUTF8StringEncoding) |error|:(missing value)
if xmlString = missing value then return false
set xmlDoc to (current application’s NSDictionary’s dictionaryWithXMLString:xmlString) as record

★Click Here to Open This Script 

AppleScript名:XMLをDictionaryに(local file)
– Created 2016-11-05 by Takaaki Naganoya
– 2016 Piyomaru Software
use AppleScript version “2.4″
use scripting additions
use framework “Foundation”
use framework “XmlToDictKit” –https://github.com/nicklockwood/XMLDictionary
–http://piyocast.com/as/archives/4304

set aFile to POSIX path of (choose file)
set aURL to current application’s |NSURL|’s fileURLWithPath:aFile
set xmlString to current application’s NSString’s alloc()’s initWithContentsOfURL:aURL encoding:(current application’s NSUTF8StringEncoding) |error|:(missing value)
if xmlString = missing value then return false
set xmlDoc to (current application’s NSDictionary’s dictionaryWithXMLString:xmlString) as record

★Click Here to Open This Script 

AppleScript名:RSSをDictionaryに(remote file)
– Created 2016-11-05 by Takaaki Naganoya
– 2016 Piyomaru Software
use AppleScript version “2.4″
use scripting additions
use framework “Foundation”
use framework “XmlToDictKit” –https://github.com/nicklockwood/XMLDictionary
–http://piyocast.com/as/archives/4304

set aURL to current application’s |NSURL|’s alloc()’s initWithString:“http://piyocast.com/as/feed”
set xmlString to current application’s NSString’s alloc()’s initWithContentsOfURL:aURL encoding:(current application’s NSUTF8StringEncoding) |error|:(missing value)
if xmlString = missing value then return false
set xmlDoc to (current application’s NSDictionary’s dictionaryWithXMLString:xmlString) as record
set aChannel to |item| of channel of xmlDoc
set aDoc1 to first item of aChannel
–>  {category:{”Application Control”, “10.10 savvy”, “10.11 savvy”, “10.12 savvy”}, dc:creator:”maro”, comments:”http://piyocast.com/as/archives/4304#comments”, title:”XMLをNSDictionaryに”, link:”http://piyocast.com/as/archives/4304″, pubDate:”Sat, 05 Nov 2016 21:21:17 +0900″, description:”オープンソースのXMLDictionary(By Nick Lockwood)をFramework化した「XmlToDictKit」を呼び出して、XMLをNSDictionaryにするAppleScr…”, guid:{__text:”http://piyocast.com/as/archives/4304″, _isPermaLink:”false”}, wfw:commentRss:”http://piyocast.com/as/archives/4304/feed/”}

★Click Here to Open This Script 

2016/10/31 listのrecordをplistにserializeして、plistをde-serializeする

Listでまとめたrecordをエンコーディングしてplist文字列にして(serialize)、さらにそれを元に戻す(deserialize)AppleScriptです。

本来、「エンコーダーとデコーダーは一緒に作る」はずのものですが、plistへのエンコードScriptしかできておらず、世の中に転がっているObjective-Cのサンプルとにらめっこしてもさっぱり分からなかったので、AppleScript Users MLに質問を投げてみたら、Shane Stanleyからあっさりと、

「これ、もうdeprecatedなmethodなんで使っちゃダメだよ。あと、deserializeするときには文字列をそのまま渡さないでね」

というアドバイスとコードそのものを教えてもらいました。というわけで、整理して掲載しておきます。

AppleScript名:listのrecordをplistにserializeして、plistをde-serializeする
– Created 2016-10-30 by Takaaki Naganoya
– Modified 2016-10-31 by Shane Stanley
– 2016 Piyomaru Software
use AppleScript version “2.4″
use scripting additions
use framework “Foundation”
–http://piyocast.com/as/archives/4296

set aList to {{theName:“Sound Track”, numberOfTimes:1721}, {theName:“Rock”, numberOfTimes:942}}
set aRes to serializeToPlistString(aList) of me
set bRes to (deserializeToPlistString(aRes) of me) as list
–>  {{numberOfTimes:1721, theName:”Sound Track”}, {numberOfTimes:942, theName:”Rock”}}

–list or record –> XML-format plist string
on serializeToPlistString(aList as {list, record})
  set pListData to current application’s NSPropertyListSerialization’s dataWithPropertyList:aList |format|:(current application’s NSPropertyListXMLFormat_v1_0) options:0 |error|:(missing value)
  
set bStr to (current application’s NSString’s alloc()’s initWithData:pListData encoding:(current application’s NSUTF8StringEncoding)) as string
  
return bStr
end serializeToPlistString

–XML-format plist string–> list or record
on deserializeToPlistString(aStr as string)
  set deStr to current application’s NSString’s stringWithString:aStr
  
set theData to deStr’s dataUsingEncoding:(current application’s NSUTF8StringEncoding)
  
set aList to current application’s NSPropertyListSerialization’s propertyListWithData:theData options:(current application’s NSPropertyListMutableContainersAndLeaves) |format|:(missing value) |error|:(missing value)
  
return aList
end deserializeToPlistString

★Click Here to Open This Script 

2016/10/30 Listのrecordをエンコーディングしてplist文字列にする

Listでまとめたrecordをエンコーディングしてplist文字列にするAppleScriptです。

ただのrecordでもなんでもいいのですが、plistのファイルに書き込むのではなく、文字列として取得します。

AppleScriptをTerminal上で呼び出して、複数のAppleScript同士でデータをやりとりする場合に、リストやレコードをそのままやりとりすることは困難です。そこで、plistの文字列にして標準出力に出すことを検討してみました。

ご注意:本Scriptはdeprecatedなmethodを使っているため、アップデート版を利用してください。

AppleScript名:Listのrecordをエンコーディングしてplist文字列にする
– Created 2016-10-30 by Takaaki Naganoya
– 2016 Piyomaru Software
use AppleScript version “2.4″
use scripting additions
use framework “Foundation”
–http://piyocast.com/as/archives/4295

set aList to {{theName:“サウンドトラック”, numberOfTimes:1721}, {theName:“ロック”, numberOfTimes:942}}

–2D Arrayをplistの文字列にエンコードする
set anArray to current application’s NSArray’s arrayWithObject:aList
set pListData to current application’s NSPropertyListSerialization’s dataFromPropertyList:anArray |format|:(current application’s NSPropertyListXMLFormat_v1_0) errorDescription:(missing value)
set bStr to (current application’s NSString’s alloc()’s initWithData:pListData encoding:(current application’s NSUTF8StringEncoding)) as string

(*
–>  ”<?xml version=\”1.0\” encoding=\”UTF-8\”?>
<!DOCTYPE plist PUBLIC \”-//Apple//DTD PLIST 1.0//EN\” \”http://www.apple.com/DTDs/PropertyList-1.0.dtd\”>
<plist version=\”1.0\”>
<array>
  <array>
    <dict>
      <key>numberOfTimes</key>
      <integer>1721</integer>
      <key>theName</key>
      <string>サウンドトラック</string>
    </dict>
    <dict>
      <key>numberOfTimes</key>
      <integer>942</integer>
      <key>theName</key>
      <string>ロック</string>
    </dict>
  </array>
</array>
</plist>

*)

★Click Here to Open This Script 

2016/10/28 ベクトルのコサイン類似度を計算する v2

ベクトル同士のコサイン類似度を計算するAppleScriptの改良版です。

「ガンダム」「アムロ・レイ」「ガンキャノン」

という3つの言葉の類似度を計算したところ、

 (1)「ガンダムとガンキャノン」
 (2)「アムロ・レイとガンキャノン」
 (3)「アムロ・レイとガンダム」

の順に類似度が計算されてしまい、「ガンキャノン問題」として問題視されました。

Apitoreさんより「ベクトルの長さで正規化するとよい」という助言をいただき、いろいろ調べて改良してみたものです。

その結果、

 (1)「ガンダムとガンキャノン」
 (2)「ガンダムとアムロ・レイ」
 (3)「アムロ・レイとガンキャノン」

の順番に計算結果が出るようになり、一安心しています。

AppleScript名:ベクトルのコサイン類似度を計算する v2
– Created 2016-10-28 by Takaaki Naganoya
– 2016 Piyomaru Software
–以下のページを参照しました
–http://www.cse.kyoto-su.ac.jp/~g0846020/keywords/cosinSimilarity.html
–http://piyocast.com/as/archives/4293

set aRec to {startTime:“1477635439753″, |word|:“ガンダム”, endTime:“1477635439754″, |log|:“Success.”, |vector|:{-0.173511996865, 0.186350002885, 0.288884997368, 0.107758000493, 0.287292987108, 0.119222998619, 0.246404007077, -0.332718014717, -0.309754997492, 0.326180011034, 0.499563008547, -0.131274998188, 0.238587006927, -0.317025989294, -0.008682000451, 0.619518995285, 0.316774994135, -0.053045999259, 0.028408000246, -0.428086012602, -0.607270002365, 0.657006978989, 0.676119029522, 0.203107997775, -0.316679000854, 0.082666002214, -0.310041993856, 0.603790998459, 0.468154996634, 0.206021994352, 0.028333999217, -0.087867997587, -0.358617991209, 0.128415003419, 0.037046000361, -0.260360985994, -0.210915997624, -0.015564999543, -0.180935993791, 0.083250999451, -0.193316996098, 0.250761002302, 0.202393993735, -0.155086994171, 0.036905001849, 0.418110996485, 0.067231997848, -0.116421997547, -0.341655999422, 0.05919200182, 0.389017999172, -0.544457018375, -0.244222998619, 0.337971001863, 0.163227006793, 0.117914997041, -0.042672999203, -0.215838998556, 0.191798001528, 0.174465000629, -0.055527999997, 0.121985003352, -0.046782001853, -0.347003012896, -0.425747990608, 0.576622009277, 0.322551995516, -0.426732987165, -0.580038011074, -0.579939007759, 0.29191800952, 0.076993003488, 0.220890000463, -0.374727010727, 0.11546599865, 0.239750996232, -0.599394023418, 0.581852018833, -0.124090999365, -0.180638998747, 0.5446190238, -0.65235298872, 0.456075012684, 0.494884997606, 0.484183996916, 0.020594999194, 0.362075001001, -0.089720003307, 0.230300992727, 0.281304001808, 0.286731004715, 0.374053001404, -0.177623003721, 0.090945996344, -0.399394005537, 0.573561012745, 0.130366995931, 0.15235799551, -0.323183000088, 0.143162995577, 0.274109989405, 0.520829021931, 0.171061992645, -0.079223997891, -0.529187977314, 0.109682999551, -0.433328002691, -0.26163700223, -0.624193012714, 1.016695022583, -0.359939008951, 0.183194994926, 0.018155999482, -0.14149799943, -0.240256994963, 0.413583993912, 0.378069013357, -0.35772100091, 0.056784998626, 0.842347025871, -0.041281998158, 0.121949002147, -0.55557101965, -0.012947999872, -0.451754003763, 0.095089003444, 0.468187004328, -0.376350998878, 0.78152102232, 0.307211011648, -0.709493994713, -0.498080998659, -0.324746012688, -0.199910998344, 0.066499002278, -0.047377999872, -0.116584002972, -0.392536014318, 0.534222006798, -0.004480999894, 0.106450997293, 0.492370009422, -0.205549001694, -0.138926997781, -0.25551199913, 0.122440002859, -0.063225999475, 0.400667995214, -0.294638991356, -0.618892014027, -0.163193002343, -0.203306004405, -0.500850975513, 0.183540001512, -0.46670499444, -0.213167995214, -0.276264995337, 0.204497992992, -0.156630992889, 0.383563011885, 0.496547013521, 0.113885998726, 0.020508000627, -0.389571994543, 0.218575999141, -0.064272001386, -0.026503000408, -0.173591002822, 0.254842013121, 0.464908987284, -0.103918999434, -0.269497007132, 0.070835001767, 0.203738003969, 0.181133002043, -0.246653005481, -0.136351004243, -0.24780100584, 0.326480001211, -0.193390995264, -0.041266001761, 0.245121002197, -0.118851996958, -0.083679996431, -0.171301007271, 0.031709998846, -0.332567989826, -0.059787001461, 0.001627000049, -0.048179998994, -0.396964997053, 0.31639200449, -0.352144986391, 0.008798000403, -0.232255995274, -0.394028007984, 0.116296000779, 0.171626001596, 0.013128999621, -0.295181006193}, processTime:“1″}

set bRec to {startTime:“1477635460487″, |word|:“アムロ・レイ”, endTime:“1477635460487″, |log|:“Success.”, |vector|:{0.03407099843, 0.10659699887, 0.127606004477, -0.13093200326, 0.17143599689, -0.386317998171, 0.223474994302, -0.63797801733, -0.21521499753, 0.215176001191, 0.607864022255, 0.176204994321, -0.184221997857, 0.361393988132, 0.16435199976, 0.652567028999, 0.242174997926, -0.325437992811, 0.394699007273, -0.393142998219, -0.312689989805, 0.173059001565, 0.660327970982, -0.07935500145, -0.34789198637, -0.223361998796, -0.153245002031, 0.175822004676, 0.104438997805, 0.50031298399, 0.16487300396, -0.138288006186, -0.054469998926, 0.100807003677, 0.05673699826, -0.067408002913, 0.017626000568, -0.07518299669, -0.201003998518, -0.005166999996, -0.088767997921, 0.615378975868, 0.126588001847, -0.127129003406, 0.159886002541, 0.374316006899, -0.03769300133, -0.050262000412, 0.063642002642, 0.169852003455, 0.409768998623, -0.453413009644, -0.122203998268, 0.294649988413, 0.11619400233, 0.576021015644, -0.117141999304, -0.486111998558, 0.283957004547, -0.101135000587, -0.078950002789, 0.173895001411, -0.083311997354, 0.028666999191, -0.21795900166, 0.184988006949, -0.185552999377, -0.399181008339, -0.098324000835, -0.352382987738, 0.075119003654, -0.17525100708, 0.373353004456, -0.152073994279, 0.051049001515, 0.110192000866, -0.726333022118, 0.334517002106, -0.075718998909, -0.354999989271, 0.655991971493, -0.298009991646, 0.508288025856, 0.243245005608, 0.239094004035, -0.086781002581, -0.161684006453, -0.507776021957, 0.261065006256, 0.284135997295, 0.307931989431, 0.213102996349, 0.136901006103, 0.397157996893, -0.464179992676, 0.262387990952, 0.380863010883, -0.071410998702, -0.165156006813, 0.135739997029, 0.283789008856, 0.820464015007, -0.359337002039, 0.155907005072, -0.330406993628, 0.400182008743, 0.119069002569, -0.182172998786, -0.147823005915, 0.674717009068, -0.637548983097, -0.110163003206, 0.025941999629, -0.274792999029, -0.184186995029, 0.543650984764, 0.189351007342, -0.354799985886, -0.005100999959, 0.318190008402, 0.088809996843, 0.300523996353, -0.336024999619, -0.279132008553, -0.489708006382, 0.119197003543, 0.357654988766, -0.009196000174, 0.908367991447, 0.127497002482, -0.877427995205, -0.362311005592, 0.045292001218, 0.228176996112, 0.003637999995, -0.021867999807, 0.264483004808, -0.531185984612, 0.075176000595, -0.258029013872, 0.180007994175, 0.549230992794, 0.085698001087, 0.164148002863, 0.198268994689, 0.206103995442, 0.182986006141, 0.262667000294, -0.509878993034, -0.44718798995, 0.136090993881, -0.18127900362, -0.148757994175, 0.263893991709, -0.386029988527, -0.198642000556, 0.220932006836, 0.202956005931, 0.048569001257, 0.194492995739, 0.180389001966, 0.697315990925, 0.139156997204, -0.228732004762, 0.201507002115, -0.043519001454, -0.419701009989, -0.424322992563, 0.085637003183, 0.513258993626, -0.90073800087, -0.365974009037, -0.043921001256, -0.012201000005, 0.343672990799, -0.352656006813, 0.335415005684, -0.584758996964, -0.045765001327, -0.614067018032, 0.095513001084, 0.461355000734, -0.371479004622, -0.612700998783, 0.043907001615, 0.56964302063, -0.364234000444, -0.080641999841, 0.140410006046, -0.180212005973, -0.543507993221, 0.225119993091, -0.285872995853, 0.08812700212, -0.299535006285, 0.026107000187, -0.221154004335, 0.39902600646, 0.160721004009, -0.433041006327}, processTime:“0″}

set cRec to {startTime:“1477635477524″, |word|:“ガンキャノン”, endTime:“1477635477524″, |log|:“Success.”, |vector|:{0.072226002812, -0.123470000923, 0.229124993086, 0.024253999814, 0.090787000954, -0.554116010666, 0.127351999283, -0.277144014835, -0.273193985224, 0.049963001162, 0.459771990776, -0.271524995565, 0.12961499393, -0.174656003714, 0.56355202198, 0.922071993351, 0.629299998283, 0.046698000282, 0.017914000899, -0.093442000449, -0.435452997684, 0.599241018295, 0.600166976452, -0.085536003113, -0.361353993416, 0.147931993008, -0.145070001483, 0.277393013239, 0.016388999298, 0.262728989124, 0.212905004621, 0.189909994602, -0.292201012373, 0.332486003637, 0.308021992445, -0.036079999059, -0.271553009748, -0.20025600493, -0.090479001403, 0.268270999193, -0.272096991539, 0.199298992753, 0.15323600173, -0.348919987679, 0.290313988924, 0.180563002825, -0.179280996323, -0.239015996456, -0.279372006655, 0.237440004945, 0.588576972485, -0.73378098011, -0.176648005843, 0.382687985897, 0.023191999644, 0.218005001545, 0.104557998478, -0.209011003375, -0.139624997973, 0.429735004902, 0.027498999611, -0.114556998014, 0.439689993858, -0.343279987574, -0.206854000688, 0.510254979134, 0.38624098897, -0.413646996021, -0.354449987411, -0.344117999077, -0.059645000845, 0.084478996694, 0.013961999677, -0.162633001804, 0.16069200635, -0.239609003067, -0.710308015347, 0.490334004164, 0.209011003375, -0.068875998259, 0.620296001434, -0.67517799139, 0.308690011501, 0.349496990442, 0.543331027031, 0.014736999758, 0.265686988831, -0.242991000414, 0.08111499995, 0.433555006981, 0.534663021564, 0.440093994141, 0.046149998903, 0.456764996052, -0.426779985428, 1.205618023872, 0.433625012636, 0.19698600471, -0.024245999753, -0.195654004812, 0.778258979321, 1.02594602108, -0.0279610008, -0.08894199878, -0.757061004639, 0.001425000024, -0.355924993753, 0.055286001414, 0.080266997218, 0.389950990677, -0.39531698823, 0.532419979572, 0.106784999371, -0.050149999559, -0.230510994792, 0.41841301322, 0.785488009453, 0.17853499949, 0.012822999619, 0.533285975456, 0.046064998955, 0.457116991282, -0.336412996054, 0.086345002055, -0.490134000778, -0.060506001115, 0.505389988422, -0.440815001726, 0.701705992222, 0.233691006899, -0.556469976902, -0.175993993878, 0.047694001347, -0.439999997616, 0.048073999584, 0.32014799118, -0.157723993063, -0.406812012196, -0.235781997442, 0.149423003197, 0.221878007054, 0.274697005749, -0.336528003216, -0.027574999258, -0.05121299997, 0.049157001078, -0.061744999141, 0.571139991283, -0.426824986935, -0.511521995068, -0.180418998003, -0.173777997494, -0.501815021038, 0.165115997195, -0.52134001255, -0.110209003091, -0.296977996826, 0.113278999925, -0.254267007113, 0.274937003851, 0.171541005373, 0.226473003626, -0.05610800162, -0.063437998295, 0.179731994867, 0.016723999754, -0.181597992778, -0.0923660025, 0.297807008028, 0.402370989323, -0.933079004288, -0.062503002584, 0.156483992934, 0.066535003483, -0.129124999046, -0.464343994856, 0.046394001693, -0.510720014572, 0.117109999061, -0.378863990307, 0.104653000832, 0.297672003508, 0.057688999921, -0.290758013725, -0.042853001505, 0.69950902462, -0.666705012321, -0.062345001847, 0.131890997291, 0.12205799669, 0.190595000982, 0.141661003232, -0.141069993377, 0.29548099637, -0.252436995506, -0.12503400445, 0.245934993029, 0.292874008417, -0.207329005003, -0.592303991318}, processTime:“0″}

set aList to |vector| of aRec
set bList to |vector| of bRec
set cList to |vector| of cRec

set aRes to calcCosinSimilarity(aList, bList) of me –ガンダムとアムロ・レイ
set bRes to calcCosinSimilarity(aList, cList) of me –ガンダムとガンキャノン
set cRes to calcCosinSimilarity(bList, cList) of me –アムロ・レイとガンキャノン

return {aRes, bRes, cRes}
–> {44.057800255168, 50.555325012947, 32.83911534787}
–(1)「ガンダムとガンキャノン」、(2)「ガンダムとアムロ・レイ」、(3)「アムロ・レイとガンキャノン」の順番

–コサイン類似度をベクターのリストから計算する
on calcCosinSimilarity(aList, bList)
  set aLen to length of aList
  
set bLen to length of bList
  
if aLenbLen then error “Not Same Item Nums”
  
  
set aRes to 0
  
repeat with i from 1 to aLen
    set a1 to (contents of item i of aList)
    
set b1 to (contents of item i of bList)
    
    
set vL to getVectorLength(a1, b1) of me
    
set normF to (1 / vL)
    
set aRes to aRes + ((a1 * normF) * (b1 * normF))
  end repeat
  
  
return aRes
end calcCosinSimilarity

–ベクトルの長さを求める
on getVectorLength(a, b)
  return getSQR(a ^ 2 + b ^ 2) of me
end getVectorLength

–平方根を求める
on getSQR(aNum)
  return (aNum ^ 0.5)
end getSQR

★Click Here to Open This Script 

2016/10/28 ベクトルのコサイン類似度を計算する

ベクトル同士の類似度を求めるために、2つのベクトル同士のコサイン類似度を計算するAppleScriptです。

なんのことやら?(^ー^;;; 

だいたい、なぜこんなものを作ってみたかといえば、Apitoreの「単語ベクトル変換【新語対応】」というWebサービスをAppleScriptから呼び出して、200次元のベクトルを取得。このベクトル同士の類似度を計算する方法を聞いてみたところ、「コサイン距離を求めればわかるよー」とのこと。

本来、単語同士の類似度を計算するサービスはApitoreの「Word2Vec-Neologd-Wiki」にあるSimilarity APIがあり、これを呼べば2つの単語の意味的な近さを求めてくれます。

ただ、ベクトル同士の近さを求める「やりかた」自体は理解しておいたほうがよいと考え、やや「車輪の再発明」的な内容であるものの、調べて、理解して、実装してみました。

なんだー、要素ごとに掛け算して足すだけでいいんじゃん(汗) というわけで、いろいろ実際に計算した内容を検証してみました。

A「富士山」B「エベレスト」C「きゃりーぱみゅぱみゅ」という3つの単語のベクトルを単語ベクトル変換【新語対応】から求め、AとB、AとC、BとCの3つのコサイン類似度の計算を行ってみました。

  富士山とエベレスト:9.96044011858
  富士山ときゃりーぱみゅぱみゅ:5.348813123563
  エベレストときゃりーぱみゅぱみゅ:6.25804549236

この結果から、これら3つの単語の間では「富士山とエベレスト」の類似度が高い、という計算結果が得られました(よかったよかった ^ー^;)。

ちなみに、A「ガンダム」B「アムロ・レイ」C「ガンキャノン」で類似度を計算してみたところ、

  ガンダムとアムロ・レイ:14.92435981554
  ガンダムとガンキャノン:17.465853286865
  アムロ・レイとガンキャノン:15.693039744314

「ガンダムとガンキャノン」というメカ同士の類似度が高いという結果が得られた一方で、アムロ・レイと距離が近いのがガンダムよりもガンキャノンだという謎の計算結果が出てきました。これは、学習データの内容によりものでしょうか。それとも、「こまけえことはいいんだよ」というレベルの問題なんでしょうか。

→ ベクトルを長さで正規化すると解決するとのこと。さぁ、勉強だ(汗)

AppleScript名:ベクトルのコサイン類似度を計算する
– Created 2016-10-28 by Takaaki Naganoya
– 2016 Piyomaru Software
–以下のページを参照しました
–http://www.cse.kyoto-su.ac.jp/~g0846020/keywords/cosinSimilarity.html

–http://piyocast.com/as/archives/4292

set aRec to {startTime:“1477632528599″, |word|:“富士山”, endTime:“1477632528599″, |log|:“Success.”, |vector|:{0.123668000102, -0.309015005827, 0.120112001896, -0.044573001564, 0.313836991787, 0.077581003308, 0.495095998049, -0.352721989155, 0.492121994495, 0.637359976768, 0.116067998111, 0.188023999333, -0.17861700058, -0.28166899085, -0.01465999987, 0.337170988321, -0.071643002331, 0.432227998972, -0.097863003612, -0.035069998354, -0.010216999799, -0.192351996899, 0.319081991911, -0.109619997442, 0.187950998545, -0.27009499073, -0.088083997369, 0.284711003304, 0.128161996603, -0.291191011667, -0.052581999451, -0.291323006153, -0.403849005699, 0.480201989412, -0.261173009872, -0.603130996227, 0.340840995312, -0.538646996021, 0.441242009401, 0.168537005782, -0.287396997213, 0.027472000569, 0.478017985821, 0.006159000099, -0.536579012871, -0.182714998722, -0.434570014477, -0.619507014751, -0.044015999883, -0.066451996565, 0.252929985523, 0.088529996574, -0.263377010822, 0.312680006027, 0.174722999334, -0.117349997163, 0.059971999377, -0.477564007044, -0.220599994063, 0.322254002094, -0.093304999173, 0.297847986221, -0.308070003986, 0.007362000179, -0.201299995184, 0.564171016216, 0.197040006518, -0.212391003966, -0.332953006029, -0.015080000274, 0.061990000308, 0.300307005644, 0.063493996859, -0.033411998302, -0.274958997965, -0.239563003182, -0.499040007591, 0.127872005105, -0.08571100235, 0.209193006158, -0.010835999623, -0.373616993427, -0.13042999804, 0.322919011116, 0.569968998432, 0.135514006019, 0.412106990814, 0.246760994196, 0.584402024746, 0.038107000291, 0.485549002886, 0.36462700367, 0.210249006748, 0.168840005994, -0.015666000545, -0.231536999345, -0.339715987444, 0.12304700166, -0.186777994037, -0.291483014822, 0.328925997019, -0.075723998249, -0.313980996609, -0.460673004389, -0.305492013693, 0.083364002407, 0.28477498889, 0.163294002414, 0.020129000768, 0.138465002179, -0.280802994967, 0.0436029993, 0.114759996533, -0.494895011187, 0.526228010654, 0.214810997248, 0.592833995819, -0.495696008205, 0.446736991405, 0.147870004177, 0.09175799787, -0.071817003191, 0.095923997462, -0.323009997606, 0.282640010118, 0.197969004512, 0.017850000411, -0.220227003098, 0.057261001319, 0.5905200243, -0.261938005686, 0.238176003098, -0.202760994434, -0.042277999222, 0.639414012432, -0.042134001851, -0.076684996486, -0.118372000754, 0.333503007889, -0.22937899828, -0.299755007029, -0.443275988102, -0.31064799428, 0.301041990519, -0.056919999421, 0.286974996328, 0.50066202879, -0.196336001158, 0.005377999973, -0.049904000014, -0.872128009796, 0.097332000732, 0.273398011923, 0.015759000555, -0.182218998671, 0.018466999754, 0.619598984718, 0.276064991951, -0.191751003265, 0.025626000017, 0.12149900198, 0.00335699995, -0.112106002867, -0.097810000181, 0.170493006706, 0.321725994349, 0.06719700247, -0.009019000456, -0.056265998632, 0.147505998611, 0.136828005314, 0.228912994266, 0.329273998737, -0.011854999699, 0.038917001337, -0.122969001532, 0.194609001279, -0.158902004361, -0.372310996056, -0.433764994144, 0.023022999987, 0.764874994755, 0.246930003166, -0.331984996796, -0.00559599977, 0.078703999519, 0.091015003622, 0.119796998799, 0.006475999951, 0.124388001859, 0.199450001121, 0.327385008335, -0.006484000012, 0.067487999797, 0.17902199924, -0.356110006571, -0.206619992852, 0.086388997734, -0.275979995728, -0.136234998703}, processTime:“0″}

set bRec to {startTime:“1477632723419″, |word|:“エベレスト”, endTime:“1477632723419″, |log|:“Success.”, |vector|:{0.232161998749, -0.021962000057, 0.018812000751, 0.019821999595, -0.172334998846, -0.207186996937, 0.131844997406, -0.304751992226, -0.044002000242, 0.681266009808, -0.321467995644, 0.303873986006, -0.19711600244, -0.806095004082, -0.046836998314, -0.160034000874, 0.036371000111, 0.706255972385, 0.053663000464, -0.246535003185, -0.13503099978, 0.073703996837, 0.197100996971, -0.171170994639, 0.193028002977, -0.215641006827, 0.220181003213, 0.603963017464, 0.208072006702, 0.188728004694, 0.088546000421, -0.361923009157, 0.07780700177, -0.059170998633, -0.068483002484, -0.805943012238, 0.122937999666, -0.318515002728, 0.465512007475, 0.264575988054, -0.308703988791, -0.162440001965, 0.371463000774, 0.011003999971, -0.44861599803, -0.052464999259, -0.079640999436, -0.742060005665, 0.004040999804, 0.00926699955, 0.106600999832, 0.023274000734, -0.225715994835, -0.023219000548, 0.003835000098, 0.330017000437, 0.450482994318, -0.321902990341, 0.221350997686, -0.031302001327, -0.074280999601, -0.057861000299, 0.122330002487, 0.359564006329, -0.182457000017, 0.15286000073, 0.300184994936, -0.264039993286, -0.23186199367, -0.212647005916, 0.022517999634, 0.06595300138, 0.322301000357, -0.685081005096, -0.207968994975, 0.125552996993, -0.568157970905, 0.373304992914, -0.317216992378, -0.200730994344, -0.078373000026, -0.423943012953, -0.145215004683, -0.07396300137, 0.174961999059, 0.653276979923, 0.163136005402, -0.386029005051, 0.318922996521, -0.397913008928, 0.446060985327, -0.020895000547, -0.65869897604, 0.412039995193, 0.343986004591, 0.147389993072, -0.001555999974, 0.19599199295, 0.128003999591, -0.560048997402, -0.031364999712, 0.103477999568, -0.62273401022, -0.152143999934, -0.769581973553, 0.329198986292, -0.024667000398, 0.061011999846, 0.203813001513, 0.300633996725, -0.918317019939, -0.110868997872, 0.058814998716, -0.473046988249, 0.317030012608, 0.014874000102, 0.756187975407, -0.373053014278, 0.016914999112, -0.286927014589, 0.038632001728, -0.183412998915, 0.010959000327, -0.632750988007, 0.469480007887, -0.218618005514, 0.113091997802, -0.177783995867, -0.068285003304, -0.108176998794, -0.384323000908, -0.139712005854, -0.224274992943, 0.281195014715, 0.324263989925, 0.230408996344, 0.055860001594, -0.027174999937, -0.079732000828, -0.390644013882, -0.561515986919, -0.64296400547, 0.074805997312, -0.134819999337, 0.699452996254, -0.097543999553, 0.650906980038, 0.016352999955, 0.237734004855, 0.100365996361, 0.281136989594, 0.074234999716, 0.2350410074, -0.754948019981, -0.447870999575, 0.170350000262, 0.469761997461, 0.075043998659, -0.560901999474, 0.050087001175, 0.067097000778, -0.204071000218, -0.089464001358, -0.604591012001, 0.399424999952, -0.188191995025, -0.184063002467, -0.275462001562, -0.438647985458, -0.028305999935, -0.10909999907, 0.306037008762, 0.553808987141, -0.042507998645, -0.089280001819, -0.030742000788, 0.307033002377, -0.102701000869, -0.226081997156, 0.122754998505, -0.509634971619, 0.82189899683, 0.012555999681, -0.309893995523, 0.617228984833, 0.13081599772, 0.264277994633, -0.521031022072, 0.369996011257, 0.402808994055, 0.169545993209, -0.144013002515, -0.26952201128, 0.852178990841, 0.489789992571, -0.407970011234, -0.20611999929, -0.025805000216, -0.042392000556, -0.245032995939}, processTime:“0″}

set cRec to {startTime:“1477632906147″, |word|:“きゃりーぱみゅぱみゅ”, endTime:“1477632906147″, |log|:“Success.”, |vector|:{0.117769002914, 0.547421991825, -0.55005300045, -0.004116999917, 0.037840001285, -0.220541000366, 0.278791993856, -0.126565992832, -0.11717300117, -0.134132996202, -0.169262006879, -0.047348998487, 0.139651998878, 0.096625000238, -0.524344027042, 0.171568006277, -0.438012003899, 0.096740998328, 0.181114003062, -0.507890999317, -0.162144005299, -0.256267994642, 0.787092983723, -0.301274001598, -0.131623998284, -0.667850971222, 0.126826003194, 0.399556994438, -0.331470012665, 0.086039997637, -0.207508996129, -0.341479003429, 0.453637003899, 0.682955026627, 0.022078000009, -0.187252998352, 0.1002940014, -0.123255997896, 0.297253012657, 0.347470998764, 0.979870975018, 0.439393997192, 0.264191001654, -0.245868995786, -0.534951984882, 0.524555027485, -0.281354993582, -0.382270008326, -0.550571024418, -0.219003006816, 0.700820982456, 0.090194001794, 0.438223004341, 0.132016003132, -0.120622001588, 0.094403997064, -0.341901004314, -0.091567002237, 0.096225000918, -0.574598014355, 0.054416999221, -0.12799499929, 0.207303002477, 0.40427801013, 0.237173005939, 0.645721971989, 0.359672009945, -0.744382977486, 0.071580000222, 0.231180995703, 0.02777400054, 0.596056997776, 0.363346010447, -0.457264989614, -0.19236600399, -0.514294981956, -0.183853000402, 0.215189993382, -0.372281998396, -0.235982000828, 0.153041005135, -0.050188001245, 0.359631001949, -0.440890014172, 0.174553006887, -0.100065998733, 0.210250005126, 0.280330985785, 0.398196995258, 0.281033992767, 0.437768012285, 0.521552026272, -0.481240004301, -0.100391998887, 0.687992990017, 0.415670007467, 0.054366998374, 0.302630990744, 0.081652998924, -0.326240986586, 0.312976002693, 0.380755007267, 0.360621005297, -0.277276992798, -0.586230993271, 0.284016996622, -0.145888999104, -0.001132000005, 0.148311004043, 0.462684988976, -0.186974003911, -0.078097999096, -0.23281699419, -0.601405024529, 0.15837700665, 0.270709007978, 0.093841001391, -0.415028005838, 0.17201000452, -0.199463993311, -0.206508994102, 0.053318999708, 0.02006999962, -0.278010010719, 0.069329999387, -0.211704999208, 0.353031992912, 0.172609999776, 0.551793992519, 0.14820599556, -0.182607993484, 0.301723003387, -0.48807901144, 0.072370998561, 0.105828002095, 0.417632997036, 0.369803994894, -0.471235990524, 0.064530000091, -0.206820994616, -0.28040599823, 0.652179002762, -0.340546995401, 0.400236010551, 0.204622000456, 0.056784000248, -0.331907987595, 0.029787000269, -0.311051011086, -0.262612998486, -0.001846999978, 0.027634000406, 0.312009006739, -0.03695999831, -0.153132006526, -0.026866000146, 0.039252001792, 0.203341007233, -0.157428994775, 0.121481001377, -0.154116004705, -0.0451150015, 0.686644017696, -0.484241992235, 0.184045001864, 0.30873298645, 0.204081997275, -0.321480989456, 0.391580998898, -0.106555998325, -0.475353002548, 0.141835004091, 0.37692001462, 0.202901005745, 0.021635999903, 0.070069000125, 0.195032000542, 0.300967991352, -0.341152012348, 0.018368000165, 0.102963000536, 0.260273009539, -0.323379009962, -0.125611007214, 0.145910993218, 0.321619004011, -0.191367998719, 0.006186999846, 0.089144997299, 0.144384995103, -0.150334000587, 0.465972006321, -0.099472999573, -0.001772999996, 0.331198006868, -0.031812999398, -0.196685001254, 0.192193999887, -0.468513011932, 0.307538002729}, processTime:“0″}

set aList to |vector| of aRec
set bList to |vector| of bRec
set cList to |vector| of cRec

set aRes to calcCosinSimilarity(aList, bList) of me –富士山とエベレスト
set bRes to calcCosinSimilarity(aList, cList) of me –富士山ときゃりーぱみゅぱみゅ
set cRes to calcCosinSimilarity(bList, cList) of me –エベレストときゃりーぱみゅぱみゅ

return {aRes, bRes, cRes}
–> {9.96044011858, 5.348813123563, 6.25804549236}–「富士山とエベレスト」の距離が一番近い

–コサイン類似度をベクターのリストから計算する
on calcCosinSimilarity(aList, bList)
  set aLen to length of aList
  
set bLen to length of bList
  
if aLenbLen then error “Not Same items”
  
  
set aRes to 0
  
repeat with i from 1 to aLen
    set a1 to contents of item i of aList
    
set b1 to contents of item i of bList
    
set c to a1 * b1
    
set aRes to aRes + c
  end repeat
  
  
return aRes
end calcCosinSimilarity

★Click Here to Open This Script 

2016/06/17 ASOCでmdfindするじっけん v4(フルパスを返す)

Spotlightの機能をCocoa経由で呼び出してmdfindコマンドのクエリーと検索対象フォルダをPOSIX pathで与えると、条件に合致するファイルのPOSIX pathをリストに入れて返してくるAppleScriptです。

以前に掲載したバージョンを実際に使おうとしたら、激しく間違っていることを発見。なんで気がつかなかったんでしょう。いえ、なんでこんな忙しいときに気づいてしまうんでしょう。

AppleScript名:ASOCでmdfindするじっけん v4(フルパスを返す)
– Created 2016-06-17 by Takaaki Naganoya
– 2016 Piyomaru Software
use AppleScript version “2.4″
use scripting additions
use framework “Foundation”

property searchRes : {}

set origPath to POSIX path of (choose folder)
set aList to spotlightSearch(origPath, “kMDItemContentType == ’net.daringfireball.markdown’”) of me

on spotlightSearch(origPath, aMDfindParam)
  
  
set my searchRes to {} –initialize
  
initiateSearchForFullPath(aMDfindParam, origPath) –Predicate & Scope Directory
  
  
–Waiting for the result
  
repeat while my searchRes = {}
    delay 0.01
  end repeat
  
  
set anObj to my searchRes’s firstObject() –Pick up the first one for test
  
if anObj = missing value then return {} –No Result
  
  
set resArray to {}
  
repeat with anItem in my searchRes
    set j to contents of anItem
    
set aPath to (j’s valueForAttribute:“kMDItemPath”) as string
    
set the end of resArray to aPath
  end repeat
  
  
return resArray
  
end spotlightSearch

on initiateSearchForFullPath(aQueryStrings, origPath)
  
  
set aSearch to current application’s NSMetadataQuery’s alloc()’s init()
  
  
current application’s NSNotificationCenter’s defaultCenter()’s addObserver:(me) selector:“queryDidUpdate:” |name|:(current application’s NSMetadataQueryDidUpdateNotification) object:aSearch
  
current application’s NSNotificationCenter’s defaultCenter()’s addObserver:(me) selector:“initalGatherComplete:” |name|:(current application’s NSMetadataQueryDidFinishGatheringNotification) object:aSearch
  
  
set aPredicate to current application’s NSPredicate’s predicateWithFormat:aQueryStrings
  
aSearch’s setPredicate:aPredicate
  
  
set aScope to current application’s NSArray’s arrayWithObjects:{origPath}
  
aSearch’s setSearchScopes:aScope
  
  
set sortKeys to current application’s NSSortDescriptor’s sortDescriptorWithKey:“kMDItemFSName” ascending:true
  
aSearch’s setSortDescriptors:(current application’s NSArray’s arrayWithObject:sortKeys)
  
  
aSearch’s startQuery()
  
end initiateSearchForFullPath

on queryDidUpdate:sender
  log sender
  
–> (NSConcreteNotification) NSConcreteNotification 0×7fa618450820 {name = NSMetadataQueryDidFinishGatheringNotification; object = }
end queryDidUpdate:

on initalGatherComplete:sender
  set anObject to sender’s object
  
anObject’s stopQuery()
  
current application’s NSNotificationCenter’s defaultCenter()’s removeObserver:me |name|:(current application’s NSMetadataQueryDidUpdateNotification) object:anObject
  
current application’s NSNotificationCenter’s defaultCenter()’s removeObserver:me |name|:(current application’s NSMetadataQueryDidFinishGatheringNotification) object:anObject
  
  
set my searchRes to anObject’s results()
end initalGatherComplete:

★Click Here to Open This Script 

2016/03/11 shellの出力結果をスペースでparseする

shellの出力結果を利用する際に、スペースでparseするAppleScriptです。

連続するスペースキャラクターでparseしつつ不要なゴミを削除して必要な項目だけ取得するというものです。

AppleScript名:shellの出力結果をスペースでparseする
– Created 2016-03-11 by Takaaki Naganoya
– 2016 Piyomaru Software
use AppleScript version "2.4"
use scripting additions
use framework "Foundation"

set a to "3 0×4248387 1920×1200 0 0 -1920 -1200 0 [main]"

set aStr to (current application’s NSString’s stringWithString:a)
–> (NSString) "3 0×4248387 1920×1200 0 0 -1920 -1200 0 [main]"

set aLine to (aStr’s componentsSeparatedByString:" ")
–> (NSArray) {"3", "", "0×4248387", "", "", "", "", "1920×1200", "", "", "", "", "", "0", "", "", "", "", "0", "", "-1920", "", "-1200", "", "", "", "", "", "0", "", "", "", "[main]"}

(aLine’s removeObject:"")
–> (NSArray) {"3", "0×4248387", "1920×1200", "0", "0", "-1920", "-1200", "0", "[main]"}

set bList to aLine as list
–>  {"3", "0×4248387", "1920×1200", "0", "0", "-1920", "-1200", "0", "[main]"}

★Click Here to Open This Script 

2016/02/28 Safariの履歴を読んでトップ10をテキストで出力する

SafariのHistory.plistを読み込んで、アクセス回数のトップ10をテキスト出力するAppleScriptです。

Safari 9.1+OS X 10.11環境を前提としています。plistの内容については、Safariのバージョンごとに変更が加わってもおかしくないので、メジャーバージョンアップ時には動作確認する必要があることでしょう。

他のアプリケーションの.plistファイルにアクセスするのはかなり野蛮な処理ですが(Sandbox環境では許可されない)、場合によっては有用なこともあるでしょう。

ちなみに、Scriptの実行例はサブマシン(MacBook Air 2011)で実行したものです。

AppleScript名:Safariの履歴を読んでトップ10をテキストで出力する
– Created 2016-02-27 by Takaaki Naganoya
– Piyomaru Software 2016
use AppleScript version “2.4″
use scripting additions
use framework “Foundation”

set libPath to (POSIX path of (path to library folder from user domain)) & “Safari/History.plist”
set aRec to retDictFromPlist(libPath) of me
set bRecList to aRec’s valueForKeyPath:“WebHistoryDates”

set bArray to sortRecListByLabel(bRecList, “visitCount”, false) of me
set outStr to “”
set aCount to 0

repeat with i from 0 to 100
  set anItem to (bArray’s objectAtIndex:i)
  
  
set aURL to (anItem’s valueForKeyPath:“”) as string
  
set aTitle to (anItem’s valueForKeyPath:“title”) as string
  
set aDispTItle to (anItem’s valueForKeyPath:“displayTitle”) as string
  
set aVisitCount to (anItem’s valueForKeyPath:“visitCount”) as string
  
set redirectURLs to (anItem’s valueForKeyPath:“redirectURLs”) as list
  
set lastVisitedDate to (anItem’s valueForKeyPath:“lastVisitedDate”) as string
  
  
if aURL does not start with “http://piyocast.com” then –自分のところのサイト関連を除外
    set aStr to ((aCount + 1) as string) & “:(” & (aVisitCount as string) & “)” & aTitle & return
    
set outStr to outStr & aStr
    
    
set aCount to aCount + 1
    
if aCount = 10 then exit repeat
    
  end if
  
  
end repeat

return outStr

(*
–>  ”1:(7657)radiko.jp
2:(608)Apple
3:(416)ソフトバンクWi-Fiスポット
4:(156)公式Apple Store(日本)- iPad Air、MacBook Pro、ほかにもたくさん
5:(125)Yahoo! JAPAN
6:(108)Mac整備済製品 - Apple Store (Japan)
7:(54)Apple-Style \”アップルなBlogをリンク\”
8:(44)PC Watch
9:(31)Facebook
10:(28)アップル - Mac Pro

*)

–Read plist
on retDictFromPlist(aPath as text)
  set thePath to current application’s NSString’s stringWithString:aPath
  
set thePath to thePath’s stringByExpandingTildeInPath()
  
set theDict to current application’s NSDictionary’s dictionaryWithContentsOfFile:thePath
  
return theDict
end retDictFromPlist

–リストに入れたレコードを、指定の属性ラベルの値でソート
on sortRecListByLabel(aRecList, aLabelStr, ascendF)
  set aArray to current application’s NSArray’s arrayWithArray:aRecList
  
set sortDesc to current application’s NSSortDescriptor’s alloc()’s initWithKey:aLabelStr ascending:ascendF
  
set sortDescArray to current application’s NSArray’s arrayWithObjects:sortDesc
  
set sortedArray to aArray’s sortedArrayUsingDescriptors:sortDescArray
  
return sortedArray
end sortRecListByLabel

★Click Here to Open This Script 

2016/01/08 レコードのリストからラベル値のみ抽出してユニーク化してソート

Cocoaの機能を用いて、レコードのリストからラベル値のみ抽出して、ユニーク化してソートして返すAppleScriptです。

AppleScript名:レコードのリストからラベル値のみ抽出してユニーク化してソート
– Created 2016-01-08 by Takaaki Naganoya
– 2016 Piyomaru Software
use AppleScript version "2.4"
use scripting additions
use framework "Foundation"

set aDic to {{field1:"test 10", field2:"test 20"}, {field1:"test 11", field2:"test 21"}, {field1:"test 12", field2:"test 22"}, {field1:"test 13", field2:"test 23"}, {field1:"test 14", field2:"test 24"}, {field1:"test 15", field2:"test 25"}, {field1:"test 16", field2:"test 26"}, {field1:"test 17", field2:"test 27"}, {field1:"test 18", field2:"test 28"}, {field1:"test 19", field2:"test 29"}, {field1:"test 10", field2:"test 20"}, {field1:"test 11", field2:"test 21"}, {field1:"test 12", field2:"test 22"}, {field1:"test 13", field2:"test 23"}, {field1:"test 14", field2:"test 24"}, {field1:"test 15", field2:"test 25"}, {field1:"test 16", field2:"test 26"}, {field1:"test 17", field2:"test 27"}, {field1:"test 18", field2:"test 28"}, {field1:"test 19", field3:"test 29"}}

set theDataSource to current application’s NSMutableArray’s arrayWithArray:aDic
set kList to retEveryKeys(theDataSource) of me
–>  {"field1", "field2", "field3"}

–リストになったRecordのすべてのアイテムのkey値を取得してユニーク化してソートして返す
on retEveryKeys(aDic)
  set aLen to aDic’s |count|()
  
set tmpKeys to {}
  
  
repeat with i from 0 to (aLen - 1)
    set aRec to (aDic’s objectAtIndex:i)
    
set keyList to (aRec’s allKeys()) as list
    
set tmpKeys to tmpKeys & keyList
  end repeat
  
  
set aRes to uniquifyAndSort1DList(tmpKeys, true) of me
  
return aRes
end retEveryKeys

–1D Listをユニーク化してソート
on uniquifyAndSort1DList(theList, aBool as boolean)
  set aArray to current application’s NSArray’s arrayWithArray:theList
  
set bArray to aArray’s valueForKeyPath:"@distinctUnionOfObjects.self"
  
set aDdesc to current application’s NSSortDescriptor’s sortDescriptorWithKey:"self" ascending:aBool selector:"compare:"
  
set cArray to bArray’s sortedArrayUsingDescriptors:{aDdesc}
  
set bList to cArray as list
  
return bList
end uniquifyAndSort1DList

★Click Here to Open This Script 

2015/10/14 テキストとリストの変換

Cocoaの機能を用いて、listとtextの相互変換を行うAppleScriptです。

List -> Text

リストをそのままテキストにするもの(できるけど)ではなく、{”a”,”b”,”c”} のようなリストを、”a–> b–> c”のようにデリミタ(区切り)文字を介して連結する処理です。最初はそれだけの目的のために作ったルーチンでした。

この「項目間を→でつなぐ」という目的で作ったサブルーチン(retArrowText)が便利で他の用途に転用しまくったため、すっかり自分ローカルの方言になってしまいました。今後は「retStrFromArrayWithDelimiter」を使っていくつもりです。

Text -> List

テキストを指定デリミタ(改行など)で区切ってリストにするものです。ついでなので作っておきました。自分ローカルで「parseByDelim」と呼んでいたもので、こちらの名前はそれほどおかしくないので、このまま行こうかと。

AppleScript名:ASOCでテキストとリストの変換
– Created 2015-10-14 by Takaaki Naganoya
– 2015 Piyomaru Software
use AppleScript version “2.4″
use scripting additions
use framework “Foundation”

set aList to {“あああああ”, “いいいいいいいい”, “ううううううううううう”, “えええええええええええ”, “おおおおおおおおおお”}
set aRes to my retStrFromArrayWithDelimiter(aList, return)
(*
“あああああ
いいいいいいいい
ううううううううううう
えええええええええええ
おおおおおおおおおお”
*)

set bList to my parseByDelim(aRes, return)
–>  {”あああああ”, “いいいいいいいい”, “ううううううううううう”, “えええええええええええ”, “おおおおおおおおおお”}

–リストを指定デリミタをはさんでテキスト化
on retStrFromArrayWithDelimiter(aList, aDelim)
  set anArray to current application’s NSArray’s arrayWithArray:aList
  
set aRes to anArray’s componentsJoinedByString:aDelim
  
return aRes as text
end retStrFromArrayWithDelimiter

on retArrowText(aList, aDelim) –自分のASでよく使うハンドラ名称なので、同じものを用意
  return my retStrFromArrayWithDelimiter(aList, aDelim)
end retArrowText

–テキストを指定デリミタでリスト化
on parseByDelim(aData, aDelim)
  set aText to current application’s NSString’s stringWithString:aData
  
set aList to aText’s componentsSeparatedByString:aDelim
  
return aList as list
end parseByDelim

★Click Here to Open This Script 

2015/09/28 NSPredicateによる正規表現を利用した部分一致抽出

Cocoaの機能を用いて、リストのレコードから正規表現による要素の抽出を行うAppleScriptです。実行にはShane StanleyのAppleScript Library「BridgePlus」のインストールが必要になります。

NSPredicateや複数条件を併記するNSCompoundPredicateで、リストに入ったレコードを抽出するのが楽すぎて、もはやこれなしにデータの抽出ができなくなりつつあります。ゴリゴリにPure AppleScriptで記述できないこともないのですが、NSPredicateが使えるだけでもASOCを覚える価値があると思えるほどです。

そんな中、徐々に記述レベルが上がってくると、無茶な抽出にもチャレンジしてみたくなるもので・・・

  「98」で始まる8桁の数字が入った要素をリストアップ。ただし、途中に出現するパターンも含む

という抽出にチャレンジしてみました(仕事で必要だったもので)。完全一致ならなんとか書けるのですが、上記の条件の文字列を「含む」ものまで抽出することを考えると、とたんに難易度が上がります。

結局、AppleのPredicate Programming Guideを総チェックして、「.*」で囲めば「条件に合うものを含む」という状態を抽出できることを見つけました(プログラミングではなくて、情報収集とかパズルのレベルですね)。

AppleScript名:ASOCでNSPredicateによる正規表現を併用した抽出
– Created 2015-09-28 by Takaaki Naganoya
– 2015 Piyomaru Software
use AppleScript version “2.4″
use scripting additions
use framework “Foundation”
use BridgePlus : script “BridgePlus” —Shane Stanley’s BridgePlus

set sampleList to {{textData:“Piyomaru”, uID:1}, {textData:“Xx Piyomaru x”, uID:2}, {textData:“xxxxx 11111111 98 x xxxxxxxx.”, uID:3}, {textData:“98x Xxxxxx (xx xxxxxxxxxx)”, uID:4}, {textData:“< < 98158113 >>”, uID:5}, {textData:“#98158084 Xxxxx Xxxxx xxxx”, uID:6}, {textData:“#98158084 Xxxxx Xxxxx xxxx”, uID:7}, {textData:“Office # 98158107″, uID:8}, {textData:“ID#98158087″, uID:9}, {textData:“98158089″, uID:10}, {textData:“00158098″, uID:11}}

–全文一致で抽出
set aRes to my filterRecListByLabel1(sampleList, “textData == ’Piyomaru’”)
–>  {​​​​​{​​​​​​​textData:”Piyomaru”, ​​​​​​​uID:1​​​​​}​​​}

–部分一致で抽出
set bRes to my filterRecListByLabel1(sampleList, “textData contains ’Piyomaru’”)
–>  {​​​​​{​​​​​​​textData:”Piyomaru”, ​​​​​​​uID:1​​​​​}, ​​​​​{​​​​​​​textData:”Xx Piyomaru x”, ​​​​​​​uID:2​​​​​}​​​}

–正規表現で抽出(8桁の数字)
set cRes to my filterRecListByLabel1(sampleList, “textData MATCHES ’\\\\d{8}’”)
–>  {​​​​​{​​​​​​​textData:”98158089″, ​​​​​​​uID:10​​​​​}, ​​​​​{​​​​​​​textData:”00158089″, ​​​​​​​uID:11​​​​​}​​​}

set dRes to my filterRecListByLabel1(sampleList, “textData MATCHES ’98\\\\d{6}’”)
–>  {​​​​​{​​​​​​​textData:”98158089″, ​​​​​​​uID:10​​​​​}​​​}

set eRes to my filterRecListByLabel1(sampleList, “textData LIKE ’*98??????*’”)
–>  {​​​​​{​​​​​​​textData:”xxxxx 11111111 98 x xxxxxxxx.”, ​​​​​​​uID:3​​​​​}, ​​​​​{​​​​​​​textData:”98x Xxxxxx (xx xxxxxxxxxx)”, ​​​​​​​uID:4​​​​​}, ​​​​​{​​​​​​​textData:”< < 98158113 >>”, ​​​​​​​uID:5​​​​​}, ​​​​​{​​​​​​​textData:”#98158084 Xxxxx Xxxxx xxxx”, ​​​​​​​uID:6​​​​​}, ​​​​​{​​​​​​​textData:”#98158084 Xxxxx Xxxxx xxxx”, ​​​​​​​uID:7​​​​​}, ​​​​​{​​​​​​​textData:”Office # 98158107″, ​​​​​​​uID:8​​​​​}, ​​​​​{​​​​​​​textData:”ID#98158087″, ​​​​​​​uID:9​​​​​}, ​​​​​{​​​​​​​textData:”98158089″, ​​​​​​​uID:10​​​​​}​​​}

set fRes to my filterRecListByLabel1(sampleList, “textData LIKE ’*\”98\”[0-9][0-9][0-9][0-9][0-9][0-9]*’”) –Oops!!
–>  {}

set gRes to my filterRecListByLabel1(sampleList, “textData LIKE ’*[0-9][0-9][0-9][0-9][0-9][0-9][0-9][0-9]*’”) –Oops!!
–>  {}

set hRes to my filterRecListByLabel1(sampleList, “textData MATCHES ’.*[98]\\\\d{6}.*’”) –OK!!
–>  {​​​​​{​​​​​​​textData:”< < 98158113 >>”, ​​​​​​​uID:5​​​​​}, ​​​​​{​​​​​​​textData:”#98158084 Xxxxx Xxxxx xxxx”, ​​​​​​​uID:6​​​​​}, ​​​​​{​​​​​​​textData:”#98158084 Xxxxx Xxxxx xxxx”, ​​​​​​​uID:7​​​​​}, ​​​​​{​​​​​​​textData:”Office # 98158107″, ​​​​​​​uID:8​​​​​}, ​​​​​{​​​​​​​textData:”ID#98158087″, ​​​​​​​uID:9​​​​​}, ​​​​​{​​​​​​​textData:”98158089″, ​​​​​​​uID:10​​​​​}​​​}

–リストに入れたレコードを、指定の属性ラベルの値で抽出
on filterRecListByLabel1(aRecList as list, aPredicate as string)
  set aArray to current application’s NSArray’s arrayWithArray:aRecList
  
set aPredicate to current application’s NSPredicate’s predicateWithFormat:aPredicate
  
set filteredArray to aArray’s filteredArrayUsingPredicate:aPredicate
  
set bList to ASify from filteredArray as list
  
return bList
end filterRecListByLabel1

★Click Here to Open This Script 

2015/09/14 地域、事業所名のリストを出現頻度カウントなどの処理を行って整形

家族から頼まれて作成したプログラムで、割と手こずったデータ処理のAppleScriptです。

Excelに入っているデータを読み取ってAppleScript側で集計処理を行ってみました。Pure AppleScript的な処理とCocoa的な処理がいろいろと入り混じっており、逆に効率が悪くなっているかもしれません(ただし、BridgePlusを活用しまくり、Cocoaの機能を利用して処理を書きまくっているので、処理速度は爆速)。

ここに掲載したScriptは、その処理の一部ですが・・・単体で実行可能なものです。

{「営業所エリア名」、「事業所名」}のペアになっているリストで頻度集計を行うというものですが、同時に「営業所エリア名」を「エリア名略称」に変換します。

Input:{{”西営業所”, “◯◯◯◯◯”}, {”四国営業所”, “●●●●”}, {”西営業所”, “◯◯◯◯◯”}}

Output:
(XXXX西部)◯◯◯◯◯ (2)
(XXXX四国)●●●●

非常に些細な処理ですが、実際に組んでみるとそれなりに手間がかかりました。

NSCountedSetにNSDictionaryを突っ込んで頻度カウントができるんじゃないかと思って試行錯誤してみたのですが、なかなかうまくいきませんでした(どうやら突っ込んでカウントはできているものの、値を取り出すのに失敗)。まだ、なかなか難しいです(汗)。

AppleScript名:地域、事業署名のリストを出現頻度カウントなどの処理を行って整形v2
– Created 2015-09-13 by Takaaki Naganoya
– 2015 Piyomaru Software
use AppleScript version “2.4″
use scripting additions
use framework “Foundation”
use BridgePlus : script “BridgePlus”

load framework

set oList to {{“西営業所”, “◯◯◯◯◯”}, {“四国営業所”, “●●●●”}, {“西営業所”, “◯◯◯◯◯”}}

set aRes to formatBranchDescriptions(oList)
–>
(*
“(XXXX西部)◯◯◯◯◯ (2)
(XXXX四国)●●●●

*)

on formatBranchDescriptions(oList)
  set labelList to {“branchName”, “elipName”}
  
set aList to BridgePlus’s sublistsIn:oList asDictionariesUsingLabels:labelList
  
  
—set aList to {{branchName:”西営業所”, elipName:”◯◯◯◯◯”}, {branchName:”四国営業所”, elipName:”●●●●”}, {branchName:”西営業所”, elipName:”◯◯◯◯◯”}}
  
  
set anArray to Cocoaify aList
  
  
set elipNameList to (anArray’s valueForKey:“elipName”) as list
  
–>  {”◯◯◯◯◯”, “●●●●”, “”◯◯◯◯◯”}
  
set eList to uniquify1DList(elipNameList) of me –ユニーク化
  
  
set outStr to “”
  
repeat with i in eList
    set j to contents of i
    
set aRes to countSpecifiedItem(elipNameList, {j}) of me
    
    
set aPredicate to current application’s NSPredicate’s predicateWithFormat_(“elipName == %@”, j)
    
set aRec to (anArray’s filteredArrayUsingPredicate:aPredicate)
    
set anItem to branchName of first item of aRec
    
set eName2 to convBranchToElip(anItem)
    
if aRes > 1 then
      set outStr to outStr & {eName2 & j & “ (” & aRes & “)”} & return
    else
      set outStr to outStr & {eName2 & j} & return
    end if
  end repeat
  
return outStr
end formatBranchDescriptions

–リスト中の指定項目の出現回数を返す
on countSpecifiedItem(aList, countItem)
  set aRes to BridgePlus’s indexesOfItems:countItem inList:aList inverting:false
  
set aCount to length of aRes
  
return aCount
end countSpecifiedItem

–1D Listをユニーク化
on uniquify1DList(theList as list)
  set aArray to current application’s NSArray’s arrayWithArray:theList
  
set bArray to aArray’s valueForKeyPath:“@distinctUnionOfObjects.self”
  
set bList to ASify from bArray as list
  
return bList
end uniquify1DList

–営業所エリア名、エリア名略称変換
on convBranchToElip(aBranch)
  set aList to {{branchName:“東京営業所”, elipName:“(XXXX東京)”}, {branchName:“千葉営業所”, elipName:“(XXXX千葉)”}, {branchName:“神奈川営業所”, elipName:“(XXXX神奈川)”}, {branchName:“西営業所”, elipName:“(XXXX西部)”}, {branchName:“四国営業所”, elipName:“(XXXX四国)”}, {branchName:“茨城営業所”, elipName:“(XXXX茨城)”}}
  
set aDic to Cocoaify aList
  
set aPredicate to current application’s NSPredicate’s predicateWithFormat_(“branchName == %@”, aBranch)
  
set aRes to (aDic’s filteredArrayUsingPredicate:aPredicate)
  
try
    set anItem to contents of first item of (aRes as list)
    
set eName to (elipName of anItem)
  on error
    set eName to “”
  end try
  
return eName
end convBranchToElip

★Click Here to Open This Script 

2015/08/25 ASOCで性別と言語コードを指定して高音質voiceを取得

Cocoaの機能を用いて、Text To Speechの音声から性別と言語を指定して、高音質のVoice名称をリストで返すAppleScriptです。

voice1.png
▲システム環境設定「音声入力と読み上げ」>「テキスト読み上げ」

voice2.png
▲OSにインストールされているVoiceリスト

男性:VoiceGenderMale
女性:VoiceGenderFemale

で性別を指定して高音質のvoice名称を取得します。

アメリカ英語(en_US)で男性の音声をどれでもいいから指定したいが、どの音声が入っているかは特定できないしデフォルトで指定されているかどうかもわからない、といった場合にある程度の見当をつけるために作ったものです。

TTS Voiceで使用可能な言語コード一覧については、「ASOCで全voiceから言語コードを抽出」のプログラムで取得できるようにしておきました。

AppleScript名:ASOCで性別と言語コードを指定して高音質voiceを取得
– Created 2015-08-25 by Takaaki Naganoya
– 2015 Piyomaru Software
use AppleScript version “2.4″
use scripting additions
use framework “Foundation”
use framework “AppKit”

set v1Res to getPremiumVoiceNameWithFiltering(“VoiceGenderMale”, “ja_JP”)
–>  {​​​​​”Otoya”​​​}

set v2Res to getPremiumVoiceNameWithFiltering(“VoiceGenderFemale”, “en_US”)
–>  {​​​​​”Allison”, ​​​​​”Ava”, ​​​​​”Jill”, ​​​​​”Samantha”​​​}

set v3Res to getPremiumVoiceNameWithFiltering(“VoiceGenderMale”, “en_GB”)
–> {”Daniel”}

–Premium Voices Only
on getPremiumVoiceNameWithFiltering(voiceGender, voiceLang)
  –Make Blank Array
  
set outArray to current application’s NSMutableArray’s arrayWithObject:{}
  
  
–Make Installed Voice List
  
set aList to current application’s NSSpeechSynthesizer’s availableVoices()
  
set bList to aList as list
  
  
repeat with i in bList
    set j to contents of i
    
set aDIc to (current application’s NSSpeechSynthesizer’s attributesForVoice:j)
    (
outArray’s addObject:aDIc)
  end repeat
  
  
–Filter Voice
  
set aStr to current application’s NSString’s stringWithString:(“VoiceLocaleIdentifier == ’” & voiceLang & “’ and VoiceGender == ’” & voiceGender & “’ and VoiceIdentifier ENDSWITH[c] ’premium’”)
  
set aPredicate to current application’s NSPredicate’s predicateWithFormat:aStr
  
set filteredArray to outArray’s filteredArrayUsingPredicate:aPredicate
  
set aReList to (filteredArray’s valueForKey:“VoiceNameRoot”) as list
  
  
return aReList
  
end getPremiumVoiceNameWithFiltering

★Click Here to Open This Script 

AppleScript名:ASOCで全voiceから言語コードを抽出
– Created 2015-08-25 by Takaaki Naganoya
– 2015 Piyomaru Software
use AppleScript version “2.4″
use scripting additions
use framework “Foundation”
use framework “AppKit”
use BridgePlus : script “BridgePlus”

load framework

set cRes to getLaunguageCodeFromTTSVoices()
–>  {​​​​​”fr_FR”, ​​​​​”zh_TW”, ​​​​​”it_IT”, ​​​​​”en_ZA”, ​​​​​”es_AR”, ​​​​​”ko_KR”, ​​​​​”ro_RO”, ​​​​​”en_IN”, ​​​​​”fr_CA”, ​​​​​”hi_IN”, ​​​​​”da_DK”, ​​​​​”en-scotland”, ​​​​​”pt_BR”, ​​​​​”zh_CN”, ​​​​​”sv_SE”, ​​​​​”es_ES”, ​​​​​”hu_HU”, ​​​​​”ar_SA”, ​​​​​”en_GB”, ​​​​​”ja_JP”, ​​​​​”fi_FI”, ​​​​​”zh_HK”, ​​​​​”tr_TR”, ​​​​​”nb_NO”, ​​​​​”pl_PL”, ​​​​​”id_ID”, ​​​​​”cs_CZ”, ​​​​​”el_GR”, ​​​​​”he_IL”, ​​​​​”ru_RU”, ​​​​​”de_DE”, ​​​​​”en_AU”, ​​​​​”nl_BE”, ​​​​​”pt_PT”, ​​​​​”th_TH”, ​​​​​”sk_SK”, ​​​​​”en_US”, ​​​​​”en_IE”, ​​​​​”nl_NL”, ​​​​​”es_MX”​​​}

on getLaunguageCodeFromTTSVoices()
  
  
–Make Blank Array
  
set outArray to current application’s NSMutableArray’s arrayWithObject:{}
  
  
–Make Installed Voice List
  
set aList to current application’s NSSpeechSynthesizer’s availableVoices()
  
set bList to aList as list
  
  
repeat with i in bList
    set j to contents of i
    
set aDIc to (current application’s NSSpeechSynthesizer’s attributesForVoice:j)
    (
outArray’s addObject:aDIc)
  end repeat
  
  
set aResArray to (outArray’s valueForKey:“VoiceLocaleIdentifier”)
  
  
set aSet to current application’s NSMutableSet’s setWithArray:aResArray
  
set aResList to aSet’s allObjects()
  
  
set bResList to BridgePlus’s listByDeletingBlanksIn:aResList –Remove Blank Items
  
  
return bResList
  
end getLaunguageCodeFromTTSVoices

★Click Here to Open This Script 

2015/07/27 ASOCでAppleScript設定ファイルの読み込み

Cocoaの機能を用いてScript Editor自身の書式設定ファイル(plist)を読み込むAppleScriptです。

とくに特殊な処理は必要なく、一般的なplistファイルに記録されたDictionaryをrecordに読み込んで、最終的にNSDataから各種データに復元しています。もうちょっとこなれた書き方もありそうですが、とりあえずデータを取り出すレベルまで書いてみた次第です。

Scriptが返している各種Cocoaのオブジェクトについては、Apple純正Script Editorでは表示されず、ASObjC Explorer 4で表示されるものを記載しています。

本当に色とフォント種別(+サイズほか関連情報)しか入っていないのにはびっくりです。

AppleScript名:ASOCでAppleScript設定ファイルの読み込み
use AppleScript version “2.4″
use scripting additions
use framework “Foundation”

set AppleScriptFontFile to “~/Library/Preferences/com.apple.applescript.plist”
set pathString to current application’s NSString’s stringWithString:AppleScriptFontFile
set newPath to pathString’s stringByExpandingTildeInPath()
set aRec to retDictFromPlist(newPath) of me

set asAttr to AppleScriptSourceAttributes of aRec
set asAttrArray to {}

repeat with i in asAttr
  
  set aCol to NSColor of i
  
set aFont to NSFont of i
  
  set aColO to (current application’s NSUnarchiver’s unarchiveObjectWithData:aCol)
  
set aFonO to (current application’s NSUnarchiver’s unarchiveObjectWithData:aFont)
  
  set the end of asAttrArray to {aColO, aFonO}
  
end repeat

asAttrArray
–>  {​​​​​{​​​​​​​(NSDeviceRGBColor) NSDeviceRGBColorSpace 0.568627 0.156863 0.564706 1, ​​​​​​​(NSFont) “Osaka 12.00 pt. P [] (0×600000249cc0) fobj=0×6000005e9800, spc=3.33″​​​​​}, ​​​​​{​​​​​​​(NSDeviceRGBColor) NSDeviceRGBColorSpace 0.372549 0.368627 0.368627 1, ​​​​​​​(NSFont) “Osaka 12.00 pt. P [] (0×600000249cc0) fobj=0×6000005e9800, spc=3.33″​​​​​}, ​​​​​{​​​​​​​(NSDeviceRGBColor) NSDeviceRGBColorSpace 0.054902 0.243137 0.984314 1, ​​​​​​​(NSFont) “Osaka 12.00 pt. P [] (0×600000249cc0) fobj=0×6000005e9800, spc=3.33″​​​​​}, ​​​​​{​​​​​​​(NSDeviceRGBColor) NSDeviceRGBColorSpace 0.470588 0.203922 0.796079 1, ​​​​​​​(NSFont) “Osaka 12.00 pt. P [] (0×600000249cc0) fobj=0×6000005e9800, spc=3.33″​​​​​}, ​​​​​{​​​​​​​(NSDeviceRGBColor) NSDeviceRGBColorSpace 0.988235 0.164706 0.109804 1, ​​​​​​​(NSFont) “Osaka 12.00 pt. P [] (0×600000249cc0) fobj=0×6000005e9800, spc=3.33″​​​​​}, ​​​​​{​​​​​​​(NSDeviceRGBColor) NSDeviceRGBColorSpace 0 0 0 1, ​​​​​​​(NSFont) “Osaka 12.00 pt. P [] (0×600000249cc0) fobj=0×6000005e9800, spc=3.33″​​​​​}, ​​​​​{​​​​​​​(NSDeviceRGBColor) NSDeviceRGBColorSpace 0.568627 0.321569 0.0666667 1, ​​​​​​​(NSFont) “Osaka 12.00 pt. P [] (0×600000249cc0) fobj=0×6000005e9800, spc=3.33″​​​​​}, ​​​​​{​​​​​​​(NSDeviceRGBColor) NSDeviceRGBColorSpace 0 0 0 1, ​​​​​​​(NSFont) “Osaka 12.00 pt. P [] (0×600000249cc0) fobj=0×6000005e9800, spc=3.33″​​​​​}, ​​​​​{​​​​​​​(NSDeviceRGBColor) NSDeviceRGBColorSpace 0.152941 0.788235 0.788235 1, ​​​​​​​(NSFont) “Osaka 12.00 pt. P [] (0×600000249cc0) fobj=0×6000005e9800, spc=3.33″​​​​​}, ​​​​​{​​​​​​​(NSDeviceRGBColor) NSDeviceRGBColorSpace 0.0588235 0.243137 0.984314 1, ​​​​​​​(NSFont) “Osaka 12.00 pt. P [] (0×600000249cc0) fobj=0×6000005e9800, spc=3.33″​​​​​}, ​​​​​{​​​​​​​(NSDeviceRGBColor) NSDeviceRGBColorSpace 0.121569 0.713726 0.988235 1, ​​​​​​​(NSFont) “Osaka 12.00 pt. P [] (0×600000249cc0) fobj=0×6000005e9800, spc=3.33″​​​​​}, ​​​​​{​​​​​​​(NSDeviceRGBColor) NSDeviceRGBColorSpace 0.505882 0.227451 0.85098 1, ​​​​​​​(NSFont) “Osaka 12.00 pt. P [] (0×600000249cc0) fobj=0×6000005e9800, spc=3.33″​​​​​}, ​​​​​{​​​​​​​(NSDeviceRGBColor) NSDeviceRGBColorSpace 0.364706 0.211765 0.572549 1, ​​​​​​​(NSFont) “Osaka 12.00 pt. P [] (0×600000249cc0) fobj=0×6000005e9800, spc=3.33″​​​​​}, ​​​​​{​​​​​​​(NSDeviceRGBColor) NSDeviceRGBColorSpace 0.0352941 0.215686 0.733333 1, ​​​​​​​(NSFont) “Osaka 12.00 pt. P [] (0×600000249cc0) fobj=0×6000005e9800, spc=3.33″​​​​​}, ​​​​​{​​​​​​​(NSDeviceRGBColor) NSDeviceRGBColorSpace 0.0313726 0.215686 0.733333 1, ​​​​​​​(NSFont) “Osaka 12.00 pt. P [] (0×600000249cc0) fobj=0×6000005e9800, spc=3.33″​​​​​}, ​​​​​{​​​​​​​(NSDeviceRGBColor) NSDeviceRGBColorSpace 0.0352941 0.215686 0.729412 1, ​​​​​​​(NSFont) “Osaka 12.00 pt. P [] (0×600000249cc0) fobj=0×6000005e9800, spc=3.33″​​​​​}, ​​​​​{​​​​​​​(NSDeviceRGBColor) NSDeviceRGBColorSpace 0.337255 0.215686 0.741176 1, ​​​​​​​(NSFont) “Osaka 12.00 pt. P [] (0×600000249cc0) fobj=0×6000005e9800, spc=3.33″​​​​​}, ​​​​​{​​​​​​​(NSDeviceRGBColor) NSDeviceRGBColorSpace 0.203922 0.12549 0.388235 1, ​​​​​​​(NSFont) “Osaka 12.00 pt. P [] (0×600000249cc0) fobj=0×6000005e9800, spc=3.33″​​​​​}​​​}

–Read plist as record
on retDictFromPlist(aPath)
  set thePath to current application’s NSString’s stringWithString:aPath
  
set thePath to thePath’s stringByExpandingTildeInPath()
  
set theDict to current application’s NSDictionary’s dictionaryWithContentsOfFile:thePath
  
return theDict as record
end retDictFromPlist

★Click Here to Open This Script 

2015/07/23 ASOCでレコードのリストをユニーク化

レコードのリスト(例:{{namae:”Piyomaru”,age:16}, {namae:”Piyoko”, age:13}})で、重複データ項目があった場合にそなえ、重複項目を削除する「ユニーク化」を行うAppleScriptObjCのScriptです。

BridgePlusを用いたバージョンと、ASObjCExtras.frameworkを用いたバージョンを掲載します。現在ではBridgePlusの使用が強く推奨されています。

AppleScript名:ASOCでレコードのリストをユニーク化(BridgePlus)
use AppleScript version “2.4″
use framework “Foundation”
use scripting additions
use script “BridgePlus”

load framework

set msRecList to {{msName:“格 陸戦型ジム 獲得済 COST: 120″, sortieTimes:12}, {msName:“狙 ジム・スナイパーカスタム 獲得済 COST: 200″, sortieTimes:6}, {msName:“狙 ジム・スナイパーカスタム 獲得済 COST: 200″, sortieTimes:6}}

set newMsList to uniquefyList(msRecList)
–>  {{sortieTimes:6, msName:”狙 ジム・スナイパーカスタム 獲得済 COST: 200″}, {sortieTimes:12, msName:”格 陸戦型ジム 獲得済 COST: 120″}}

–レコードのリストをユニーク化
on uniquefyList(aList)
  set msArray to Cocoaify aList
  
set aRes to current application’s NSSet’s setWithArray:(msArray’s allObjects())
  
set bRes to aRes’s allObjects()
  
set cRes to ASify from bRes as list
  
return cRes
end uniquefyList

★Click Here to Open This Script 

AppleScript名:ASOCでレコードのリストをユニーク化(ASObjCExtras.framework)
use AppleScript version “2.4″
use framework “Foundation”
use framework “ASObjCExtras”
use scripting additions

set msRecList to {{msName:“格 陸戦型ジム 獲得済 COST: 120″, sortieTimes:12}, {msName:“狙 ジム・スナイパーカスタム 獲得済 COST: 200″, sortieTimes:6}, {msName:“狙 ジム・スナイパーカスタム 獲得済 COST: 200″, sortieTimes:6}}

set newMsList to uniquefyList(msRecList)
–>  {{sortieTimes:6, msName:”狙 ジム・スナイパーカスタム 獲得済 COST: 200″}, {sortieTimes:12, msName:”格 陸戦型ジム 獲得済 COST: 120″}}

–レコードのリストをユニーク化
on uniquefyList(aList)
  set msArray to current application’s SMSFord’s Cocoaify:aList
  
set aRes to current application’s NSSet’s setWithArray:(msArray’s allObjects())
  
set bRes to aRes’s allObjects()
  
set cRes to bRes’s ASify() as list
  
return cRes
end uniquefyList

★Click Here to Open This Script