8
5

More than 5 years have passed since last update.

文字列から辞典で使うような「インデックス文字」を取得する

Last updated at Posted at 2014-02-23

この記事の二番煎じです。
文字列からあ行など取得する
ちょっと調べたら面白かったので、記事にまとめてみました。

仕様

  • 「あ〜わ」、もしくは、「A〜Z」の見出し文字を返す
  • 先頭の文字から、インデックス文字が見つかるまで探索する
  • 見出し文字が含まれていない場合には空文字@""を返す
  • NSStringのカテゴリとして実装

ソース

NSString+BTKIndexString.h
#import <Foundation/Foundation.h>

@interface NSString (BTKIndexString)

- (NSString*) btkIndexString;

@end
NSString+BTKIndexString.m
#import "NSString+BTKIndexString.h"

@implementation NSString (BTKIndexString)

- (NSString*) btkIndexString
{
    for(int i = 0; i < self.length; i++){
        // Upper Case Letter
        NSMutableString *keyStr = [self substringWithRange:NSMakeRange(i, 1)].uppercaseString.mutableCopy;
        // Full Witdh -> Half Width
        CFStringTransform((CFMutableStringRef)keyStr, NULL, kCFStringTransformFullwidthHalfwidth, FALSE);
        // Katakana -> Hiragana
        CFStringTransform((CFMutableStringRef)keyStr, NULL, kCFStringTransformHiraganaKatakana, TRUE);

        unichar uc = [keyStr characterAtIndex:0];
        switch (uc) {
            // Alphabets
            case L'A':
            case L'B':
            case L'C':
            case L'D':
            case L'E':
            case L'F':
            case L'G':
            case L'H':
            case L'I':
            case L'J':
            case L'K':
            case L'L':
            case L'M':
            case L'N':
            case L'O':
            case L'P':
            case L'Q':
            case L'R':
            case L'S':
            case L'T':
            case L'U':
            case L'V':
            case L'W':
            case L'X':
            case L'Y':
            case L'Z':
                return keyStr.copy;

            // Hiragana Characters
            // http://www.unicode.org/charts/PDF/U3040.pdf
            case L'ぁ':
            case L'あ':
            case L'ぃ':
            case L'い':
            case L'ぅ':
            case L'う':
            case L'ぇ':
            case L'え':
            case L'ぉ':
            case L'お':
                return @"あ";
            case L'か':
            case L'が':
            case L'き':
            case L'ぎ':
            case L'く':
            case L'ぐ':
            case L'け':
            case L'げ':
            case L'こ':
            case L'ご':
                return @"か";
            case L'さ':
            case L'ざ':
            case L'し':
            case L'じ':
            case L'す':
            case L'ず':
            case L'せ':
            case L'ぜ':
            case L'そ':
            case L'ぞ':
                return @"さ";
            case L'た':
            case L'だ':
            case L'ち':
            case L'ぢ':
            case L'っ':
            case L'つ':
            case L'づ':
            case L'て':
            case L'で':
            case L'と':
            case L'ど':
                return @"た";
            case L'な':
            case L'に':
            case L'ぬ':
            case L'ね':
            case L'の':
                return @"な";
            case L'は':
            case L'ば':
            case L'ぱ':
            case L'ひ':
            case L'び':
            case L'ぴ':
            case L'ふ':
            case L'ぶ':
            case L'ぷ':
            case L'へ':
            case L'べ':
            case L'ぺ':
            case L'ほ':
            case L'ぼ':
            case L'ぽ':
                return @"は";
            case L'ま':
            case L'み':
            case L'む':
            case L'め':
            case L'も':
                return @"ま";
            case L'ゃ':
            case L'や':
            case L'ゅ':
            case L'ゆ':
            case L'ょ':
            case L'よ':
                return @"や";
            case L'ら':
            case L'り':
            case L'る':
            case L'れ':
            case L'ろ':
                return @"ら";
            case L'ゎ':
            case L'わ':
            case L'ゐ':
            case L'ゑ':
            case L'を':
            case L'ん':
                return @"わ";
            case L'ゔ':
                return @"う";

            // Small Letters
            case L'ゕ':
            case L'ゖ':
                return @"か";

            // Katakana Phonetic Extensions
            // http://www.unicode.org/charts/PDF/U31F0.pdf
            case L'ㇰ':
                return @"か";
            case L'ㇱ':
            case L'ㇲ':
                return @"さ";
            case L'ㇳ':
                return @"た";
            case L'ㇴ':
                return @"な";
            case L'ㇵ':
            case L'ㇶ':
            case L'ㇷ':
            case L'ㇸ':
            case L'ㇹ':
                return @"は";
            case L'ㇺ':
                return @"ま";
            case L'ㇻ':
            case L'ㇼ':
            case L'ㇽ':
            case L'ㇾ':
            case L'ㇿ':
                return @"ら";
            default:
                continue;
        }
    }
    return @"";
}

@end

実行結果

abc -> A
アイスクリーム -> あ
☆ほし☆ -> は
ヴォーカル -> う
ㇰ -> か

豆知識

unicharの定義

ソース内にあるように、Lをつけることで日本語等のunicharもそのまま定義できます。

ユニコードの並び順

「ゕ」(3095)、「ゖ」(3096)は、「ん」(3093)、「ゔ」(3094)の後ろにあります。
今回のSwitch文はコード順に並べているので、同じインデックス文字が複数回現れている部分があります。

実はひらがなよりカタカナの方が多い

http://www.taishukan.co.jp/kokugo/webkoku/series003_03.html
アイヌ語対応の関係で、対応するひらがなのないカタカナがあります。
これはカタカナ->ひらがな変換で変換されないので、そのままSwitch文に追加してあります。

パフォーマンス

パフォーマンスが重要なら、CFStringTransformを使わずに全部switch caseに列挙した方が良さそう。
サンプルコードじゃなくて、ライブラリとして作るならそっちかな。

8
5
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
8
5