おひとり

できる限りひとりで楽しむための情報やプログラミング情報など。

【Swift 5】文字列を数値として処理(map)し、また文字列に戻す方法

文字列を数値(Int, UInt32)としてmap処理する

あまりありませんが、文字列を数値として処理したい場合があります。
例えば。ABC...を受け取って、それらをBCD...と1つずつ文字をずらしたい場合などでです。
ここでは、文字列を数値へと変換し、そしてまた文字列に戻すプログラムを関数型プログラミングのスタイルで書いてみたいと思います。

サンプルコード

ここでは以下の仕様でサンプルプログラムを書いてみます。少し不思議な仕様ですが。。。笑
※Swiftでは"A"..."Y"といったパターンマッチが使えよというサンプルにしたかった。

  • A~Yの文字の場合、右に1つシフトする。(例:Bの場合、Cになる。)
  • b~zの文字の場合、左に1つシフトする。(例:bの場合、aになる。)
  • Z、a、その他の文字の場合はそのまま出力する。
    上記仕様のshift()関数を作成してみます。
func shift(_ str: String) -> String {
    return text.unicodeScalars
        .map { (scalar) -> UInt32 in
            switch scalar {
            case "A"..."Y": return scalar.value + 1
            case "b"..."z": return scalar.value - 1
            default: return scalar.value
            }
        }
        .compactMap(UnicodeScalar.init)
        .map(Character.init)
        .map(String.init)
        .joined()
}

let text = "bcdDEF"
let result = shift(text)
print(result) // abcEFG

文字列(String)から数値(UInt32)へ

unicodeScalarsプロパティにより、String.UnicodeScalarView構造体を取得することができます。
こちらは、Unicode.Scalar構造体のコレクションとなっており、イテレートすることができます。
Unicode.Scalar構造体から、実際の値(UInt32構造体)を取得するには、valueプロパティにアクセスします。

次のように書くことができます。

let scalars = "漢字も😊OK!".unicodeScalars.map{s -> UInt32 in s.value}
print(scalars) // [28450, 23383, 12418, 128522, 79, 75, 33]

数値(UInt32)から文字列(String)へ

ここでは関数型プログラミングのスタイルで、4ステップを経て文字列へと変換しています。

let scalars: [UInt32] = [28450, 23383, 12418, 128522, 79, 75, 33]
let str = scalars.compactMap(UnicodeScalar.init)
    .map(Character.init)
    .map(String.init)
    .joined()

print(str) // 漢字も😊OK!
  1. UnicodeScalar.initでUInt32からUnicode.Scalarに変換する。
  2. UnicodeScalar.initでCharacterに変換する。
  3. String.initでStringに変換する。
  4. .joined()でそれぞれの文字列を結合する。

UInt32からUnicodeScalarへの変換はcompactMap()で行っています。
これは、UnicodeScalar.initで変換できなかった(nilになった)要素を排除するためです。
Character構造体はString内の1文字を表す構造体です。
joined()を利用して簡潔に書くため、一度各CharacterをStringに変換しています。

まとめ

StringからUInt32への変換は次のように行う。
String→String.UnicodeScalarView→UnicodeScalar→UInt32

UInt32からStringへの変換は次のように行う。 [UInt32]→[UnicodeScalar]→[String]→joined()→String

参考リンク

developer.apple.com developer.apple.com

f:id:hitoridehitode:20190616162725j:plain