2つの漢字をパーツごとに分解し、それぞれの分解したパーツからそれを使用している漢字を検索。2つのグループ間で共通して存在している漢字を抽出することで「部品が共通する文字」をリストアップする処理を擬似的に実現しているAppleScriptです。
macOSの日本語入力プログラムで実装している、「部品が共通な漢字を検索」機能っぽいものを目指したものです。例によって、掲載プログラムリストでは部品が足りずに実行できないので、以下のすべての部品を含むScriptバンドルのアーカイブをダウンロードして実行してください。
–> Download listupKanjiWithCommonParts(including AppleScript Libraries and json data)
「際」「隆」という文字を指定すると、
--> {"際", "障", "隠", "隣", "阪", "防", "阻", "附", "降", "限", "陛", "院", "陣", "除", "陥", "陪", "腹", "堕", "陰", "墜", "陳", "陵", "陶", "陸", "険", "陽", "隅", "隆", "隊", "階", "随", "隔", "隙"}
という結果を返してきます。Mac mini M1で0.46秒ぐらいです。処理時間はデータによっては大幅に増える場合がありますが、そういうものだと思ってください。テストした範囲内では最悪で1.6秒ぐらいかかりました。もともとのJSONデータを(日本の)常用漢字の範囲内だけにシェイプアップすれば半分以下の速度で実行できると思います。
いろいろ細かく高速化のための記述していますが、実測値で0.02秒ぐらい速くなっているだけなので、わかりやすさを優先して高速化のための記述はすべて外してしまったほうがよいかもしれません。
割とロマン系の「役に立つんだかどうか不明だけど、作れることがわかったので作ってみた」プログラムです。
AppleScript名:漢字をパーツに分解して部品が共通する文字を検索.scptd |
— – Created by: Takaaki Naganoya – Created on: 2021/12/14 — – Copyright © 2021 Piyomaru Software, All Rights Reserved — use AppleScript version "2.7" use framework "Foundation" use scripting additions use jkLib : script "jyoyoKanjiLib" –常用漢字一覧を返してくるAppleScriptライブラリ script jsonStr property aJsonDict : missing value property jKanji : missing value property vOut : missing value end script script spd0 property aList : {} property bList : {} property cList : {} end script property NSString : a reference to current application’s NSString property NSCountedSet : a reference to current application’s NSCountedSet property NSJSONSerialization : a reference to current application’s NSJSONSerialization property NSUTF8StringEncoding : a reference to current application’s NSUTF8StringEncoding set aTarg to "際" set (aList of spd0) to getRelatedCharacters(aTarg) of me set bTarg to "隆" set (bList of spd0) to getRelatedCharacters(bTarg) of me set (cList of spd0) to (aList of spd0) & (bList of spd0) set cRes to returnDuplicatesOnly((cList of spd0)) of me –> {"際", "障", "隠", "隣", "阪", "防", "阻", "附", "降", "限", "陛", "院", "陣", "除", "陥", "陪", "腹", "堕", "陰", "墜", "陳", "陵", "陶", "陸", "険", "陽", "隅", "隆", "隊", "階", "随", "隔", "隙"} on returnDuplicatesOnly(aList as list) script spd1 property bList : {} property dupList : {} end script set aSet to NSCountedSet’s alloc()’s initWithArray:aList set (bList of spd1) to (aSet’s allObjects()) as list set (dupList of spd1) to {} repeat with i in (bList of spd1) set aRes to (aSet’s countForObject:i) if aRes > 1 then set the end of (dupList of spd1) to (contents of i) end if end repeat return (dupList of spd1) end returnDuplicatesOnly on getRelatedCharacters(aTarg as string) set aVector to parseKanjiToParts(aTarg) of me set (vOut of jsonStr) to {} repeat with i in aVector set j to contents of i set tmpOut to searchKanjiFromElementJ(j) of me if tmpOut is not equal to missing value then set (vOut of jsonStr) to (vOut of jsonStr) & tmpOut end if end repeat set tmp2 to makeUniqueListFrom((vOut of jsonStr)) of me return tmp2 end getRelatedCharacters on cleanUp1DList(aList as list, cleanUpItems as list) script spd2 property bList : {} end script set (bList of spd2) to {} repeat with i in aList set j to contents of i if j is not in cleanUpItems then set the end of (bList of spd2) to j end if end repeat return (bList of spd2) end cleanUp1DList on parseKanjiToParts(aTarg) set outList to {} set kList to listupQueryKeysForKanji() of me repeat with i in kList set j to contents of i set aTargL to ((aJsonDict of jsonStr)’s valueForKey:j) as list if aTarg is in aTargL then set the end of outList to j end if end repeat return outList end parseKanjiToParts on searchKanjiFromElementJ(aQueryStr) if (aJsonDict of jsonStr) = missing value then my init() if (jKanji of jsonStr) = missing value then my initJ() set aRes to (aJsonDict of jsonStr)’s valueForKey:aQueryStr if aRes = missing value then return missing value set cArray to aRes’s arrayByAddingObjectsFromArray:(jKanji of jsonStr) set cRes to returnDuplicatesOnly(cArray) of me return cRes end searchKanjiFromElementJ on searchKanjiFromElement(aQueryStr) if (aJsonDict of jsonStr) = missing value then my init() set aRes to (aJsonDict of jsonStr)’s valueForKey:aQueryStr if aRes = missing value then return missing value return aRes as list end searchKanjiFromElement on listupQueryKeysForKanji() if (aJsonDict of jsonStr) = missing value then my init() set aRes to (aJsonDict of jsonStr)’s allKeys() return aRes as list end listupQueryKeysForKanji –Pure AS風のパラメータ記述 on makeUniqueListFrom(theList) set theSet to current application’s NSOrderedSet’s orderedSetWithArray:theList return (theSet’s array()) as list end makeUniqueListFrom on initJ() set (jKanji of jsonStr) to (current application’s NSArray’s arrayWithArray:(retJyouyouKanji() of jkLib)) end initJ on init() –https://github.com/yagays/kanjivg-radical set aPath to (POSIX path of (path to me)) & "Contents/Resources/element2kanji.json" set jsonString to NSString’s alloc()’s initWithContentsOfFile:(aPath) encoding:(NSUTF8StringEncoding) |error|:(missing value) set jsonData to jsonString’s dataUsingEncoding:(NSUTF8StringEncoding) set (aJsonDict of jsonStr) to NSJSONSerialization’s JSONObjectWithData:jsonData options:0 |error|:(missing value) end init |