Archive for the 'NSMutableSet' Category

2017/05/20 最大公約数を求めるv2

2つの数の最大公約数を求めるAppleScriptです。

素数チェックや素因数分解を作ったので、この手の計算を行ってみました。

AppleScript名:最大公約数を求めるv2
– Created 2017-05-20 by Takaaki Naganoya
– 2017 Piyomaru Software
use AppleScript version "2.4"
use scripting additions
use framework "Foundation"
–http://piyocast.com/as/archives/4653

set aRes to getGCDbetweenTwoNums(12, 18) of me
–> 6

–2つの数の最大公約数を求める
on getGCDbetweenTwoNums(aNum, bNum)
  set aRes to getPrimeFactor(aNum) of me
  
set bRes to getPrimeFactor(bNum) of me
  
  
–2つのリストを集合として扱い、積集合を求める
  
set aSet to current application’s NSMutableSet’s setWithArray:aRes
  
set bSet to current application’s NSMutableSet’s setWithArray:bRes
  
aSet’s intersectSet:bSet
  
set cRes to aSet’s allObjects() as list
  
  
set dRes to multipleListElements(cRes) of me
  
return dRes
end getGCDbetweenTwoNums

–与えられた数を素因数分解する
on getPrimeFactor(aTargNum)
  copy aTargNum to a
  
set pFactList to {}
  
  
repeat
    set pRes to checkPrimeNumber(a) of me
    
if pRes = true then
      set the end of pFactList to a
      
return pFactList
    end if
    
    
set aFactor to checkFactor(a) of me
    
set the end of pFactList to aFactor
    
set a to a div aFactor
  end repeat
end getPrimeFactor

–素数チェック
on checkPrimeNumber(aNum)
  repeat with i from 2 to aNum - 1
    if aNum mod i is equal to 0 then
      return false
    end if
  end repeat
  
return true
end checkPrimeNumber

–素因数チェック
on checkFactor(aNum)
  repeat with i from 2 to aNum - 1
    if aNum mod i is equal to 0 then
      return i
    end if
  end repeat
end checkFactor

–リスト内の要素をすべて乗算する
on multipleListElements(aList)
  set aNum to 1
  
set aRes to 1
  
repeat with i in aList
    set aRes to aRes * (aNum * i)
  end repeat
  
return aRes
end multipleListElements

★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 

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

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

Shane Stanleyから指摘があって、「そこもっと短くかけるよ〜」ということで、大幅に短くなりました(Thanks !!)。NSMutableSetを使うのは、とってもいい方法だと思います。

AppleScript名:レコードのリストからラベル値のみ抽出してユニーク化してソート v2
– Created 2016-01-08 by Takaaki Naganoya
– Modified 2016-01-08 by Shane Stanley (retEveryKeys)
– 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 tempSet to current application’s NSMutableSet’s |set|()
  
repeat with aDict in aDic
    (tempSet’s addObjectsFromArray:(aDict’s allKeys()))
  end repeat
  
return (tempSet’s allObjects()’s sortedArrayUsingSelector:"compare:") as list
end retEveryKeys

★Click Here to Open This Script 

2015/09/11 与えられたテキストの言語を自動判別して対応する言語のTTS Voiceで読み上げ

Cocoaの機能を用いて、与えられたテキストの言語を自動判別して対応する言語のTTS Voiceで読み上げするAppleScriptです。Shane StanleyのAppleScript Libraryである「BridgePlus」(フリー)のインストールが必要です。

こういうのがやりたくて、地道に部品を揃えてきたわけで・・・やらないわけにはいきません。

ただし、思ったよりも泥沼に足を突っ込みかけました。食後のハイキングのはずが、雪山で遭難しかけたという印象です。

NSSpeechSynthesizerのavailableVoices()は「インストールされていないTTS Voice」も返してくるため、せっかくテキストの言語を特定して、TTS Voiceを取得しても・・・インストールされていないTTS Voiceが返ってくるとお手上げです(T_T)。

tts_voice_list.png

英語だとNSLinguisticTaggerによる判定で”en”が、フランス語だと”fr”が返ってきますが、”en”はあくまで英語を示すものであり、”en_GB”もあれば”en_US”もあれば、”en_IN”(インド)、”en-scotland”(スコットランド)、”en_ZA”(南アフリカ)もあるわけです(自分も物好きですが、南アフリカのTTS Voiceはインストールしていません)。

“en”をキーにして、全TTS Voiceから言語コードを取得し、最初にヒットした言語コードが”en_ZA”であれば南アフリカのTTS Voiceでsayコマンドの実行を行おうとしてしまうので、”en”を”en-US”に置き換えるような、つじつまあわせの処理が必要になってしまいました(もう少しうまいやり方もありそうですが、食後の散歩のレベルを超えてしまいますので)。

実際に実戦レベルのAppleScriptを書いてみるまで、見えてこない「落とし穴」もあるので、こうして細かいScriptを書いておくという作業はなかなかあなどれません、、、

AppleScript名:与えられたテキストの言語を自動判別して対応する言語のTTS Voiceで読み上げ
– Created 2015-09-11 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 aRes to getVoiceLanguageFromTTSVoices() –Language Code

–English, French, Japanese, Chinese
set cList to {“With the new MacBook, we set out to do the impossible.”, “Le nouveau MacBook est le résultat d’un défi presque impossible”, “新しいMacBookとともに、私たちは不可能だと思えることに挑みました。”, 于全新 MacBook,我们给自己定了一个几乎不可能实现的目}

–各言語テキストでループ
repeat with i in cList
  set j to contents of i
  
set aLang to specifyLanguageOfText(j) –テキストから言語コードを取得
  
  
–つじつまあわせ。ちょっとカッコ悪い
  
–(NSSpeechSynthesizerのavailableVoicesでインストールされていないVoiceまで返ってくることへの対策)
  
if aLang = “en” then
    set aLang to “en-US”
  else if aLang = “fr” then
    set aLang to “fr-FR”
  else if aLang = “ja” then
    set aLang to “ja-JP”
  end if
  
  
–全ボイス中から言語をサポートしているものを抽出
  
repeat with ii in aRes
    set jj to contents of ii
    
    
if (jj as text) is equal to (aLang as text) then
      
      
–最初にヒットした言語コードでPremium Voiceを検索
      
set v1fList to getPremiumVoiceNameWithFiltering(“VoiceGenderFemale”, jj)
      
set v1mList to getPremiumVoiceNameWithFiltering(“VoiceGenderMale”, jj)
      
set v1List to v1fList & v1mList
      
      
if v1List = {} then
        –Premium Voiceでヒットしなかった場合に、すべてのVoiceを検索
        
set v2fList to getAllVoiceNameWithFiltering(“VoiceGenderFemale”, jj)
        
set v2mList to getAllVoiceNameWithFiltering(“VoiceGenderMale”, jj)
        
set v2List to v2fList & v2mList
        
        
if v2List = {} then
          display dialog “この言語(” & jj & “)をサポートするTTS Voiceはインストールされていません。” –Error
          
exit repeat
        else
          copy v2List to v1List
        end if
        
      end if
      
      
repeat with iii in v1List
        set aVoice to contents of iii
        
try
          –総当たりでSayコマンド実行(インストールされていないTTS Voiceも取得できてしまうため)
          
tell current application
            say j using aVoice
          end tell
          
exit repeat
        end try
      end repeat
      
      
exit repeat
    end if
  end repeat
  
end repeat

–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 aPredicate to current application’s NSPredicate’s predicateWithFormat_(“VoiceLanguage == %@ and VoiceGender == %@ and VoiceIdentifier ENDSWITH[c] %@”, voiceLang, voiceGender, “premium”)
  
set filteredArray to outArray’s filteredArrayUsingPredicate:aPredicate
  
set aReList to (filteredArray’s valueForKey:“VoiceName”) as list
  
  
return aReList
  
end getPremiumVoiceNameWithFiltering

–All Voices (VoiceLanguageで抽出)
on getAllVoiceNameWithFiltering(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 aPredicate to current application’s NSPredicate’s predicateWithFormat_(“VoiceLanguage == %@ and VoiceGender == %@”, voiceLang, voiceGender)
  
  
set filteredArray to outArray’s filteredArrayUsingPredicate:aPredicate
  
set aReList to (filteredArray’s valueForKey:“VoiceName”) as list
  
  
return aReList
  
end getAllVoiceNameWithFiltering

on getLocaleIdentifierFromTTSVoices()
  –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 getLocaleIdentifierFromTTSVoices

on getVoiceLanguageFromTTSVoices()
  –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:“VoiceLanguage”)
  
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 getVoiceLanguageFromTTSVoices

on specifyLanguageOfText(aStr)
  set aNSstring to current application’s NSString’s stringWithString:aStr
  
set tagSchemes to current application’s NSArray’s arrayWithObjects:(current application’s NSLinguisticTagSchemeLanguage)
  
set tagger to current application’s NSLinguisticTagger’s alloc()’s initWithTagSchemes:tagSchemes options:0
  
tagger’s setString:aNSstring
  
set aLanguage to tagger’s tagAtIndex:0 |scheme|:(current application’s NSLinguisticTagSchemeLanguage) tokenRange:(missing value) sentenceRange:(missing value)
  
return aLanguage as text
end specifyLanguageOfText

–1D Listをユニーク化してソート
on uniquifyAndSort1DList(theList as list, 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 (ASify from cArray) as list
  
return bList
end uniquifyAndSort1DList

–文字置換
on repChar(aStr, targStr, repStr)
  set aString to current application’s NSString’s stringWithString:aStr
  
set bString to aString’s stringByReplacingOccurrencesOfString:targStr withString:repStr
  
set cString to (ASify from bString) as string
  
return cString
end repChar

★Click Here to Open This Script 

2015/08/26 ASOCで性別と言語コードを指定してTTS voiceを取得 v2

Cocoaの機能を用いて、Text To Speechの音声から性別と言語を指定して、TTS Voice名称をリストで返すAppleScriptです。最初のバージョンに対して、「Premium」voiceに限定しないvoice名取得ルーチン「getAllVoiceNameWithFiltering」を追加しています。ほかに、機能的な差異はありません。

前バージョンに対し、Shane StanleyからNSPredicateの指定について、

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

って、書いてあるけど引数をNSPredicateの指定文字列から分離したほうがクォートで囲む囲まないで悩まなくていいから、分離しといたほうがいいよ(意訳)という指摘があって・・・実際、NSPredicate以外のコードはすぐに書けたものの・・・クォートの指定でけっこう試行錯誤して悩んでいたので、まったくその通り(^ー^;;;;

set aPredicate to current application’s NSPredicate’s predicateWithFormat_(”VoiceLocaleIdentifier == %@ and VoiceGender == %@ and VoiceIdentifier ENDSWITH[c] %@”, voiceLang, voiceGender, “premium”)

とか(ここで「predicateWithFormat_」とアンダースコアで書かないと構文確認をパスできないところにASOCの闇と、Shaneの試行錯誤を感じます、、、)、

set aPredicate to current application’s NSPredicate’s predicateWithFormat:”VoiceLocaleIdentifier == %@ and VoiceGender == %@ and VoiceIdentifier ENDSWITH[c] %@” argumentArray:{voiceLang, voiceGender, “premium”}

みたいに書いたほうがシンプルでいいよ的な話で、まさにそのとおり。で、いろいろ書き換えておきました。

各TTS Voiceについては、性別、言語、国などのほかに「年齢」というパラメータも持っているのですが、年齢を条件にして綿密に絞り込む・・・というほどには、TTS Voiceの数が多くないので、年齢は考慮していません。

これ(↑)を掲載するまでに、「クリップボードの内容をスタイル付きテキストで取得する方法」について調べ、調べきれなかったので、do shell script使いまくりの昔作ったAppleScriptでHTMLに書き出した、というオチもありました。Cocoaのクリップボード関連、普段使わないうえに、いざ真剣に調べだしてもあんまりまとまったまともでわかりやすい情報がなくて困りものです。

AppleScript名:ASOCで性別と言語コードを指定してTTS voiceを取得 v2
– Created 2015-08-25 by Takaaki Naganoya
– Modified 2015-08-26 by Shane Stanley, 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 v1Res to getPremiumVoiceNameWithFiltering(“VoiceGenderMale”, “ja_JP”)
–>  {​​​​​”Otoya”​​​}

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

set v3Res to getAllVoiceNameWithFiltering(“VoiceGenderFemale”, “en_US”)
–>  {​​​​​”Agnes”, ​​​​​”Allison”, ​​​​​”Ava”, ​​​​​”Jill”, ​​​​​”Kathy”, ​​​​​”Princess”, ​​​​​”Samantha”, ​​​​​”Vicki”, ​​​​​”Victoria”​​​}

–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 aPredicate to current application’s NSPredicate’s predicateWithFormat_(“VoiceLocaleIdentifier == %@ and VoiceGender == %@ and VoiceIdentifier ENDSWITH[c] %@”, voiceLang, voiceGender, “premium”)
  
set filteredArray to outArray’s filteredArrayUsingPredicate:aPredicate
  
set aReList to (filteredArray’s valueForKey:“VoiceName”) as list
  
  
return aReList
  
end getPremiumVoiceNameWithFiltering

–All Voices
on getAllVoiceNameWithFiltering(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 aPredicate to current application’s NSPredicate’s predicateWithFormat_(“VoiceLocaleIdentifier == %@ and VoiceGender == %@”, voiceLang, voiceGender)
  
  
set filteredArray to outArray’s filteredArrayUsingPredicate:aPredicate
  
set aReList to (filteredArray’s valueForKey:“VoiceName”) as list
  
  
return aReList
  
end getAllVoiceNameWithFiltering

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 aDict to (current application’s NSSpeechSynthesizer’s attributesForVoice:j)
    (
outArray’s addObject:aDict)
  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/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/01/19 2Dリストから、指定アイテムNoで、指定データが該当する最初のものを返す v3

2D Listから、指定アイテムNoが指定データとイコールの要素を返すAppleScriptです。

{{”piyomaru”, 1}, {”Piyomaru Software”, 2}, {”Naganoya”, 3}, {”Takaaki”, 4}, {”MacBook Pro Retina mid 2012″, 5}}

という2D Listがあった場合に、各アイテム中のアイテムNo.が1(item 1)のデータが”Takaaki”のものについて、

{”Takaaki”, 4}

というデータを、該当するデータがなかった場合には{}を返します。

AppleScript名:2Dリストから、指定アイテムNoで、指定データが該当する最初のものを返す v3
– Created 2015-01-19 by Takaaki Naganoya
– 2014 Piyomaru Software
use AppleScript version "2.4"
use scripting additions
use framework "Foundation"
use framework "ASObjCExtras"

set aList to {{"piyomaru", 1}, {"Piyomaru Software", 2}, {"Naganoya", 3}, {"Takaaki", 4}, {"MacBook Pro Retina mid 2012", 5}}

set gList to searchInListByIndexItem(aList, 1, "Takaaki")
–> {"Takaaki", 4}

–2Dリストから、指定インデックスアイテムで、指定データが該当する最初のものを返す
on searchInListByIndexItem(aList as list, itemNum as integer, hitData as string)
  –ListからNSMutableSetへの型変換
  
set setKey to current application’s NSMutableSet’s setWithArray:aList
  
  
–Predicate Stringを組み立てる
  
if itemNum < 1 then return {}
  
set aPredicateStr to ("SELF[" & (itemNum - 1) as string) & "] == ’" & hitData & "’"
  
  
–抽出
  
set aPredicate to current application’s NSPredicate’s predicateWithFormat:aPredicateStr
  
set aRes to (setKey’s filteredSetUsingPredicate:aPredicate)
  
set bRes to aRes’s allObjects()
  
  
–NSArrayからListに型変換して返す
  
set cRes to (bRes’s ASify()) as list
  
  
if cRes is not equal to {} then
    set cRes to contents of first item of cRes
  end if
  
  
return cRes
end searchInListByIndexItem

★Click Here to Open This Script 

2014/12/25 アプリケーションのローカライズ分布を取得する v5

/Applicationsフォルダ内に入っているアプリケーションのローカライズ言語の度数分布を取得するAppleScriptのバージョンアップ版です。

1つのアプリケーションが複数の重複するローカライズ情報を持っているケース({”de”, “English”, “fr”, “French”, “German”, “ja”, “Japanese”})があり、1つのアプリケーションから情報を取得する段階で重複を除去するルーチンを作成。重複を排除して({”German”, “English”, “French”,”Japanese”})のように整理して取得するように変更しました。

また、/Applicationsフォルダの直下のアプリケーションのファイルしか取得していなかったので、mdfindで/Applicationsフォルダ以下すべてのアプリケーションを取得するように変更。

また、言語名ではなく出現頻度でソートするように変更しました。

途中で、mdfindでアプリケーションのファイルを抽出する処理を試していたら、サブフォルダ内のアプリケーションが出てこないという問題があり・・・開発マシンのSSD内のspotlightの検索辞書が壊れていたようで、再生成したら正常に動作するようになりました。mdfindの処理の落とし穴です。

マイナー言語(失礼!)をこまかくフォローしているのはGoogleアプリかと思っていたら、VLCでした。OSがサポートしていない言語用のローカライズを行っても意味はないのですが、ムービーの字幕表示などの関係でしょうか?

AppleScript名:アプリケーションのローカライズ分布を取得する v5
– Created 2014-12-23 by Takaaki Naganoya
– Changed 2014-12-24 by Shane Stanley
– Changed 2014-12-25 by Takaaki Naganoya

use AppleScript version “2.4″
use scripting additions
use framework “Foundation”
use framework “ASObjCExtras”

–mdfindで指定フォルダ以下にあるすべてのアプリケーションファイルを取得
set apPath1 to (path to applications folder) as string
set apList to getFileListWithSpotLight(“kMDItemContentType”, “com.apple.application-bundle”, apPath1) of me

set theCountedSet to current application’s NSCountedSet’s |set|()

–各アプリケーションのローカリゼーション情報を取得する
repeat with i in apList
  set j to contents of i
  
  
–指定アプリケーションのローカライズ言語を取得。重複を除去
  
set locList to getSpecifiedAppFilesLocalizationList(j) of me
  
–> {”de”, “English”, “fr”, “French”, “German”, “ja”, “Japanese”}
  
—-> {”German”, “English”, “French”,”Japanese”}
  
  
set locArray to (current application’s SMSFord’s Cocoaify:locList)
  
  
set theEnumerator to locArray’s objectEnumerator()
  
repeat
    set aValue to theEnumerator’s nextObject()
    
if aValue is missing value then exit repeat
    
    (
theCountedSet’s addObject:aValue)
  end repeat
end repeat

–NSCountedSetをNSMutableArrayに変換
set theArray to current application’s NSMutableArray’s array()
set theEnumerator to theCountedSet’s objectEnumerator()

–NSMutableArrayから順次取り出して、NSArrayに対してDictionaryを追加
repeat
  set aValue to theEnumerator’s nextObject()
  
if aValue is missing value then exit repeat
  
theArray’s addObject:(current application’s NSDictionary’s dictionaryWithObjects:{aValue, (theCountedSet’s countForObject:aValue)} forKeys:{“theName”, “numberOfTimes”})
end repeat

–出現回数(numberOfTimes)で降順ソート
set theDesc to current application’s NSSortDescriptor’s sortDescriptorWithKey:“numberOfTimes” ascending:false
theArray’s sortUsingDescriptors:{theDesc}

return theArray as list

–> {{theName:”English”, numberOfTimes:733}, {theName:”Japanese”, numberOfTimes:404}, {theName:”French”, numberOfTimes:266}, {theName:”German”, numberOfTimes:265}, {theName:”Italian”, numberOfTimes:219}, {theName:”Spanish”, numberOfTimes:203}, {theName:”Dutch”, numberOfTimes:165}, {theName:”Chinese (China)”, numberOfTimes:149}, {theName:”Swedish”, numberOfTimes:133}, {theName:”Korean”, numberOfTimes:131}, {theName:”Russian”, numberOfTimes:129}, {theName:”Chinese (Taiwan)”, numberOfTimes:127}, {theName:”Portuguese”, numberOfTimes:124}, {theName:”Polish”, numberOfTimes:118}, {theName:”Danish”, numberOfTimes:117}, {theName:”Finnish”, numberOfTimes:110}, {theName:”Norwegian”, numberOfTimes:100}, {theName:”Czech”, numberOfTimes:92}, {theName:”Turkish”, numberOfTimes:90}, {theName:”Hungarian”, numberOfTimes:87}, {theName:”Greek”, numberOfTimes:76}, {theName:”Ukrainian”, numberOfTimes:75}, {theName:”Romanian”, numberOfTimes:74}, {theName:”Portuguese (Portugal)”, numberOfTimes:70}, {theName:”Slovak”, numberOfTimes:69}, {theName:”Catalan”, numberOfTimes:63}, {theName:”Croatian”, numberOfTimes:63}, {theName:”Arabic”, numberOfTimes:61}, {theName:”Thai”, numberOfTimes:61}, {theName:”Hebrew”, numberOfTimes:60}, {theName:”Indonesian”, numberOfTimes:58}, {theName:”Vietnamese”, numberOfTimes:57}, {theName:”Malay”, numberOfTimes:56}, {theName:”Spanish (Mexico)”, numberOfTimes:49}, {theName:”Base”, numberOfTimes:46}, {theName:”Portuguese (Brazil)”, numberOfTimes:22}, {theName:”Norwegian Bokmål”, numberOfTimes:21}, {theName:”Chinese (Simplified)”, numberOfTimes:19}, {theName:”Chinese”, numberOfTimes:14}, {theName:”English (United Kingdom)”, numberOfTimes:12}, {theName:”Bulgarian”, numberOfTimes:12}, {theName:”Chinese (Traditional)”, numberOfTimes:11}, {theName:”Latvian”, numberOfTimes:10}, {theName:”Lithuanian”, numberOfTimes:9}, {theName:”Slovenian”, numberOfTimes:9}, {theName:”Japanese (Japan)”, numberOfTimes:9}, {theName:”Czech (Czech Republic)”, numberOfTimes:9}, {theName:”Estonian”, numberOfTimes:8}, {theName:”Ukrainian (Ukraine)”, numberOfTimes:8}, {theName:”Spanish (Spain)”, numberOfTimes:7}, {theName:”Turkish (Turkey)”, numberOfTimes:7}, {theName:”Hungarian (Hungary)”, numberOfTimes:6}, {theName:”Danish (Denmark)”, numberOfTimes:6}, {theName:”Russian (Russia)”, numberOfTimes:6}, {theName:”French (XM)”, numberOfTimes:6}, {theName:”Swedish (Sweden)”, numberOfTimes:6}, {theName:”Serbian”, numberOfTimes:6}, {theName:”Norwegian Bokmål (Norway)”, numberOfTimes:6}, {theName:”Dutch (Netherlands)”, numberOfTimes:6}, {theName:”Persian”, numberOfTimes:5}, {theName:”Korean (South Korea)”, numberOfTimes:5}, {theName:”Finnish (Finland)”, numberOfTimes:5}, {theName:”Italian (Italy)”, numberOfTimes:5}, {theName:”German (Germany)”, numberOfTimes:5}, {theName:”French (Canada)”, numberOfTimes:5}, {theName:”French (France)”, numberOfTimes:5}, {theName:”Polish (Poland)”, numberOfTimes:5}, {theName:”Hindi”, numberOfTimes:5}, {theName:”English (United States)”, numberOfTimes:5}, {theName:”Hebrew (Israel)”, numberOfTimes:4}, {theName:”Arabic (United Arab Emirates)”, numberOfTimes:4}, {theName:”Spanish (Latin America)”, numberOfTimes:4}, {theName:”Romanian (Romania)”, numberOfTimes:4}, {theName:”Spanish (Namibia)”, numberOfTimes:4}, {theName:”Filipino”, numberOfTimes:4}, {theName:”Spanish (Laos)”, numberOfTimes:4}, {theName:”empty”, numberOfTimes:4}, {theName:”Greek (Greece)”, numberOfTimes:4}, {theName:”Telugu”, numberOfTimes:3}, {theName:”Malayalam”, numberOfTimes:3}, {theName:”Icelandic”, numberOfTimes:3}, {theName:”Kannada”, numberOfTimes:3}, {theName:”Galician”, numberOfTimes:3}, {theName:”Bengali”, numberOfTimes:3}, {theName:”Gujarati”, numberOfTimes:3}, {theName:”Marathi”, numberOfTimes:3}, {theName:”Tamil”, numberOfTimes:3}, {theName:”Belarusian”, numberOfTimes:3}, {theName:”Albanian”, numberOfTimes:2}, {theName:”Mongolian”, numberOfTimes:2}, {theName:”French (Morocco)”, numberOfTimes:2}, {theName:”Georgian”, numberOfTimes:2}, {theName:”Sinhala”, numberOfTimes:2}, {theName:”jp”, numberOfTimes:2}, {theName:”ua”, numberOfTimes:2}, {theName:”Amharic”, numberOfTimes:2}, {theName:”English (United Arab Emirates)”, numberOfTimes:2}, {theName:”Finnish (FL)”, numberOfTimes:2}, {theName:”Catalan (Spain)”, numberOfTimes:2}, {theName:”Basque”, numberOfTimes:2}, {theName:”English (Israel)”, numberOfTimes:2}, {theName:”Norwegian (NB)”, numberOfTimes:2}, {theName:”Oriya”, numberOfTimes:1}, {theName:”Punjabi”, numberOfTimes:1}, {theName:”Serbo-Croatian”, numberOfTimes:1}, {theName:”Walloon”, numberOfTimes:1}, {theName:”Corsican”, numberOfTimes:1}, {theName:”Sorani Kurdish”, numberOfTimes:1}, {theName:”Chinese (Hong Kong SAR China)”, numberOfTimes:1}, {theName:”Breton”, numberOfTimes:1}, {theName:”Cornish”, numberOfTimes:1}, {theName:”Chiga”, numberOfTimes:1}, {theName:”Aragonese”, numberOfTimes:1}, {theName:”Macedonian”, numberOfTimes:1}, {theName:”Japan”, numberOfTimes:1}, {theName:”Bosnian”, numberOfTimes:1}, {theName:”Ganda”, numberOfTimes:1}, {theName:”Tetum”, numberOfTimes:1}, {theName:”Welsh”, numberOfTimes:1}, {theName:”Armenian”, numberOfTimes:1}, {theName:”Kyrgyz”, numberOfTimes:1}, {theName:”Scottish Gaelic”, numberOfTimes:1}, {theName:”Afrikaans”, numberOfTimes:1}, {theName:”Zulu”, numberOfTimes:1}, {theName:”Swahili”, numberOfTimes:1}, {theName:”Burmese”, numberOfTimes:1}, {theName:”Chinese (Traditional, Taiwan)”, numberOfTimes:1}, {theName:”ct”, numberOfTimes:1}, {theName:”Tagalog”, numberOfTimes:1}, {theName:”Kazakh”, numberOfTimes:1}, {theName:”Bengali (India)”, numberOfTimes:1}, {theName:”Pashto”, numberOfTimes:1}, {theName:”Nepali”, numberOfTimes:1}, {theName:”Acoli”, numberOfTimes:1}, {theName:”Friulian”, numberOfTimes:1}, {theName:”Norwegian Nynorsk”, numberOfTimes:1}, {theName:”Asturian”, numberOfTimes:1}, {theName:”Thai (Thailand)”, numberOfTimes:1}, {theName:”Khmer”, numberOfTimes:1}, {theName:”Irish”, numberOfTimes:1}, {theName:”American”, numberOfTimes:1}, {theName:”Fulah”, numberOfTimes:1}, {theName:”Chinese (Traditional, Hong Kong SAR China)”, numberOfTimes:1}, {theName:”Occitan”, numberOfTimes:1}, {theName:”Interlingua”, numberOfTimes:1}, {theName:”Uzbek”, numberOfTimes:1}, {theName:”Azerbaijani”, numberOfTimes:1}}

–指定アプリケーションファイルの、指定Localeにおけるローカライズ言語リストを求める。重複を排除
on getSpecifiedAppFilesLocalizationList(anAppAlias as alias)
  
  
set aURL to (current application’s SMSFord’s URLFrom:anAppAlias)
  
set aBundle to current application’s NSBundle’s bundleWithURL:aURL
  
  
set theNSLocale to current application’s NSLocale’s localeWithLocaleIdentifier:“en” –Output Locale Name in English (en)
  
  
–Get Localization Info
  
set locList to aBundle’s localizations()
  
–> {”de”, “English”, “fr”, “French”, “German”, “ja”, “Japanese”}
  
set theEnumerator to locList’s objectEnumerator()
  
  
set theSet to current application’s NSMutableSet’s |set|()
  
  
repeat
    set aValue to theEnumerator’s nextObject()
    
if aValue is missing value then exit repeat
    
    
set theName to (theNSLocale’s displayNameForKey:(current application’s NSLocaleIdentifier) value:aValue)
    
    
if theName is missing value then
      –”English”や”French”などは、missing valueが返ってくるので、”English”や”French”などをそのまま追加
      
theSet’s addObject:aValue
    else
      –”de”や”fr”などは、”German”や”French”が返ってくるので、それを追加
      
theSet’s addObject:theName
    end if
  end repeat
  
  
–NSCountedSetをNSMutableArrayに変換
  
set theArray to current application’s NSMutableArray’s array()
  
set theEnumerator to theSet’s objectEnumerator()
  
  
–NSMutableArrayから順次取り出して、NSArrayに対してDictionaryを追加
  
repeat
    set aValue to theEnumerator’s nextObject()
    
if aValue is missing value then exit repeat
    
theArray’s addObject:aValue
  end repeat
  
  
return theArray as list
  
end getSpecifiedAppFilesLocalizationList

–指定階層下で、指定メタデータが指定パラメータであるファイルを取得(alias list)
on getFileListWithSpotLight(aMetaDataItem as string, aParam as string, startDir as {alias, string})
  set sDirText to quoted form of POSIX path of startDir
  
set shellText to “/usr/bin/mdfind ’” & aMetaDataItem & ” == \”" & aParam & “\”’ -onlyin “ & sDirText
  
try
    set aRes to do shell script shellText
  on error
    return {}
  end try
  
set pList to paragraphs of aRes
  
set aList to {}
  
repeat with i in pList
    set aPath to POSIX file i
    
set aPath to aPath as alias
    
set the end of aList to aPath
  end repeat
  
return aList
end getFileListWithSpotLight

★Click Here to Open This Script 

2014/11/22 リストから抽出(asoc)

リストから条件に合う項目だけを抽出するAppleScriptです。

こういう感じで1D Listだけでなく2D Listを抽出できると便利でしょう。ああ、2D Listの抽出をやりたい、、、

AppleScript名:listの項目をフィルタリング(項目文字長)
– Created 2014-11-21 by Takaaki Naganoya
– 2014 Piyomaru Software
use AppleScript version “2.4″
use scripting additions
use framework “Foundation”
use framework “ASObjCExtras”

set aList to {“piyomaru”, “Piyomaru Software”, “Naganoya”, “Takaaki”, “MacBook Pro Retina mid 2012″}

set bList to filterListUsingPredicate(aList, “length > 8″) –文字列長が8文字より長い項目を返す
–> {”MacBook Pro Retina mid 2012″, “Piyomaru Software”}

set cList to filterListUsingPredicate(aList, “SELF MATCHES ’.*e$’”) –正規表現で末尾が”e”
–> {”Piyomaru Software”}

set dList to filterListUsingPredicate(aList, “SELF LIKE ’piyo*’”)
–> {”piyomaru”}

set eList to filterListUsingPredicate(aList, “SELF LIKE[c] ’piyo*’”)
–> {”piyomaru”, “Piyomaru Software”}

set fList to filterListUsingPredicate(aList, “SELF CONTAINS[c] ’Piyo’”)
–> {”piyomaru”, “Piyomaru Software”}

on filterListUsingPredicate(aList as list, aPredicateStr as string)
  –ListからNSArrayへの型変換
  
set setKey to current application’s NSMutableSet’s setWithArray:aList
  
  
–抽出
  
set aPredicate to current application’s NSPredicate’s predicateWithFormat:aPredicateStr
  
set aRes to (setKey’s filteredSetUsingPredicate:aPredicate)
  
set bRes to aRes’s allObjects()
  
  
–NSArrayからListに型変換して返す
  
set cRes to (bRes’s ASify()) as list
  
return cRes
end filterListUsingPredicate

★Click Here to Open This Script 

2014/11/18 listの共通項を返す(asoc)

2つのListをくらべて、共通項を返すAppleScriptです。

Cocoaの流儀にしたがって、Cocoaの機能を使って実装してみました。

AppleScript名:listの共通項を返す
– Created 2014-11-18 by Takaaki Naganoya
– 2014 Piyomaru Software
use AppleScript version “2.4″
use scripting additions
use framework “Foundation”
use framework “ASObjCExtras”

set aList to {1, 2, 3, 4, 5}
set bList to {0, 1, 2, 4, 5, 6}

set aRes to getSameItemsInLists(aList, bList) of me
–> {2, 5, 1, 4}

on getSameItemsInLists(aList as list, bList as list)
  
  
–ASオブジェクトをCocoaオブジェクトに変換
  
set aArray to current application’s NSArray’s arrayWithArray:aList
  
set bArray to current application’s NSArray’s arrayWithArray:bList
  
  
– まとめる
  
set allSet to current application’s NSMutableSet’s setWithArray:aArray
  
allSet’s addObjectsFromArray:bArray
  
  
–重複する要素のみ抜き出す
  
set duplicateSet to current application’s NSMutableSet’s setWithArray:aArray
  
duplicateSet’s intersectSet:(current application’s NSSet’s setWithArray:bArray)
  
  
–重複部分だけを返す
  
set resArray to duplicateSet’s allObjects()
  
  
set resList to resArray’s ASify() as list
  
  
return resList
  
end getSameItemsInLists

★Click Here to Open This Script 

2014/11/18 list同士のdiffをとる(asoc)

2つのListのdiffをとるAppleScriptです。

検索していろいろ調べ、主にこちらのページの内容を参考にして、Cocoaの流儀にしたがって、Cocoaの機能を使って実装してみました。

以前にAppleScriptだけで実装したものもありますが、データ量が増えるとこちらの方が有利と思われます。

・・・などと書いていたら、Shane Stanleyが2つのAppleScriptの実行速度を計測するツール「Script Geek v.1.27」を公開していました

geek.png

この用途のために作られたとしか思えないツールなので、素直に使っておきましょう。指定回数実行して、平均実行時間を計測してくれるツールです。

実際に使ってみると、

(1)テストデータ作成部分を時間計測してほしくない
(2)計測結果をグラフ表示してほしい
(3)テスト中に画面の内容をアップデートしたほうがいい

といった率直な感想が(^ー^;;

それはいいとして、ASだけで実装したものとASOCで実装したものだとASOCの方が120倍速いという結果が出ました。ASだけで実装した方は、けっこう忙しいときに書いたらしく処理内容が入り組んでおり「どうしてこう書いたんだろう」という話が思い出せません、、、

また、繰り返し実行するとASOCの処理速度が(一桁ぐらい)上がるのに驚きました(初回実行時は0.27秒なのに、平均実行速度が0.03秒、、、)。

(4)各計測結果を数値またはグラフで表示

があると、どういった傾向があるのか分かってよいでしょう。

AppleScript名:listのdiffをとる
– Created 2014-11-18 by Takaaki Naganoya
– 2014 Piyomaru Software
use AppleScript version “2.4″
use scripting additions
use framework “Foundation”
use framework “ASObjCExtras”

set aList to {1, 2, 3, 4, 5}
set bList to {0, 1, 2, 4, 5, 6}

set aRes to diffLists(aList, bList) of me
–> {0, 6, 3}

on diffLists(aList as list, bList as list)
  –以下を参照
  
–http://qiita.com/ar_tama/items/b69d6ab5c505be89c414
  
  
–ASオブジェクトをCocoaオブジェクトに変換
  
set aArray to current application’s NSArray’s arrayWithArray:aList
  
set bArray to current application’s NSArray’s arrayWithArray:bList
  
  
– まとめる
  
set allSet to current application’s NSMutableSet’s setWithArray:aArray
  
allSet’s addObjectsFromArray:bArray
  
  
–重複する要素のみ抜き出す
  
set duplicateSet to current application’s NSMutableSet’s setWithArray:aArray
  
duplicateSet’s intersectSet:(current application’s NSSet’s setWithArray:bArray)
  
  
–重複部分を削除する
  
allSet’s minusSet:duplicateSet
  
set resArray to allSet’s allObjects()
  
  
set resList to resArray’s ASify() as list
  
  
return resList
  
end diffLists

★Click Here to Open This Script 

AppleScript名:listのdiffをとる(時間計測用)
– Created 2014-11-18 by Takaaki Naganoya
– 2014 Piyomaru Software
use AppleScript version “2.4″
use scripting additions
use framework “Foundation”
use framework “ASObjCExtras”

script spd
  property aList : {}
  
property bList : {}
end script

set aList of spd to {}
set bList of spd to {}

repeat 1000 times
  set the end of aList of spd to random number from 1 to 1000
  
set the end of bList of spd to random number from 1 to 1000
end repeat

set aRes to diffLists(aList of spd, bList of spd) of me

on diffLists(aList as list, bList as list)
  –以下を参照
  
–http://qiita.com/ar_tama/items/b69d6ab5c505be89c414
  
  
–ASオブジェクトをCocoaオブジェクトに変換
  
set aArray to current application’s NSArray’s arrayWithArray:aList
  
set bArray to current application’s NSArray’s arrayWithArray:bList
  
  
– まとめる
  
set allSet to current application’s NSMutableSet’s setWithArray:aArray
  
allSet’s addObjectsFromArray:bArray
  
  
–重複する要素のみ抜き出す
  
set duplicateSet to current application’s NSMutableSet’s setWithArray:aArray
  
duplicateSet’s intersectSet:(current application’s NSSet’s setWithArray:bArray)
  
  
–重複部分を削除する
  
allSet’s minusSet:duplicateSet
  
set resArray to allSet’s allObjects()
  
  
set resList to resArray’s ASify() as list
  
  
return resList
  
end diffLists

★Click Here to Open This Script 

AppleScript名:listのdiffをASだけでとる(時間計測用)

script spd
  property aList : {}
  
property bList : {}
end script

set aList of spd to {}
set bList of spd to {}

repeat 1000 times
  set the end of aList of spd to random number from 1 to 1000
  
set the end of bList of spd to random number from 1 to 1000
end repeat

set aRes to diffList(aList of spd, bList of spd) of listDiffKit
–> {{0, 9, 11}, {5}}

script listDiffKit
  
  
–リスト同士のdiffをとる
  
on diffList(aaList, bbList)
    copy {aaList, bbList} to {aList, bList} –fix?
    
set notExistInBlist to {}
    
    
if aList is equal to bList then
      return {{}, {}}
    end if
    
    
repeat with i in aList
      set j to contents of i
      
if j is in bList or j is equal to bList then
        set bList to deleteSpecifiedItemFromList(bList, j) of me
      else
        set the end of notExistInBlist to j
      end if
    end repeat
    
    
return {notExistInBlist, bList}
  end diffList
  
  
–指定内容の要素をリストから削除して返す
  
on deleteSpecifiedItemFromList(aList, anItem)
    set iCount to 1
    
repeat with i in aList
      set j to contents of i
      
if j = anItem then
        set aaList to oneItemDelete(aList, iCount) of me
        
return aaList
      end if
      
set iCount to iCount + 1
    end repeat
    
    
return aList
    
  end deleteSpecifiedItemFromList
  
  
–リスト中の指定要素を削除して返す
  
on oneItemDelete(aList, chgNum)
    set newList to {}
    
set aLen to length of aList
    
    
if chgNum = 1 then
      set aLen to length of aList
      
if aLen > 1 then
        set maeList to items 2 thru aLen of aList
        
set newList to maeList
      else
        set newList to {}
      end if
    else if chgNum = aLen then
      set maeList to items 1 thru (aLen - 1) of aList
      
set newList to maeList
      
    else
      set maeList to items 1 thru (chgNum - 1) of aList
      
set atoList to items (chgNum + 1) thru -1 of aList
      
set newList to maeList & atoList
    end if
    
    
return newList
  end oneItemDelete
  
  
on retDelimedText(aList, aDelim)
    set aText to “”
    
set curDelim to AppleScript’s text item delimiters
    
set AppleScript’s text item delimiters to aDelim
    
set aText to aList as text
    
set AppleScript’s text item delimiters to curDelim
    
return aText
  end retDelimedText
  
  
–文字置換ルーチン
  
on repChar(origText, targStr, repStr)
    set {txdl, AppleScript’s text item delimiters} to {AppleScript’s text item delimiters, targStr}
    
set temp to text items of origText
    
set AppleScript’s text item delimiters to repStr
    
set res to temp as text
    
set AppleScript’s text item delimiters to txdl
    
return res
  end repChar
end script

★Click Here to Open This Script