LoginSignup
3
3

More than 3 years have passed since last update.

【swift】文字列を一文字ずつに分割する時のArray("hoge")の型について

Last updated at Posted at 2021-01-24

文字列を1文字ずつに分割したい!
競技プログラミングを解いているとよく出くわしますね。

解決方法としては


let str = "hoge"

let separatedStr = Array(str)
print(separatedStr)
 // ["h", "o", "g", "e"]

という感じでArray()の()の中に文字列を入れれば、一文字ずつ分割してくれます。

でも、これで分割された文字列の配列はString型ではなくCharacter型なのです。

Character型とは

developer.apple.comによると、
"A single extended grapheme cluster that approximates a user-perceived character."
(google翻訳: ユーザーが知覚する文字を近似する単一の拡張書記素クラスター。)

なんか難しく書いてますがとりあえず、
「人間が自然に認識できる最小の"1文字の型"」
と認識していただければ大丈夫です。

問題なのは、String型とは明確に違うってことです。
特にInt型に変換するときに問題になってきます。

Int型への変換(例: ABC083B - Some Sums

2桁以上の数字に対して、各桁の和を算出したいです。
(例: "13"だったら1+3 = 4、"624"だったら6+2+4 = 12)

まず、与えられた数字列を1文字ずつに分解します。

let digits = "13" //String型

let separatedDigits = Array(digits) //Character型の配列
print(separatedDigits)  //["1","3"]

さて、当然Int型に直さないと計算できないので、
この後["1","3"][1,3]に直します。

ただString型の感覚で

let intDigits = separatedDigits.map({Int($0)!})

ってやったら
Cannot convert value of type 'String.Element' (aka 'Character') to expected argument type 'String'
というエラーが出ます。
swift5のVersion 12.3ではCharacter型から直接Int型には変換できないためです。

なので、

let intDigits = separatedDigits.map({Int(String($0))!})

として一旦String型を経由させてください。

その後はいつも通りreduceで配列内の足し算を行えばいいので、

let result = intDigits.reduce(0, +)

print(result) //4

で導出完了です。

コード全文

let digits = "13"

let separatedDigits = Array(digits)
let intDigits = separatedDigits.map({Int(String($0))!}) //数字列の分割

let result = intDigits.reduce(0, +)
print(result) //4

【1/31追記】

コメントにて@masakihori様からご教示いただきました!
Array()を挟まなくとも、そのままmapを掛ければ分解できます。

let digits = "13"
let intDigits = digits.map({Int(String($0))!}) 
print(intDigits) //[1,3]

map関数は「すべての要素に対して同じ処理を掛ける」関数なので、
Stringのすべての要素 = 当該Stringを構成している文字(Character)」へ同じ処理を施してくれるのですね。

参考文献

3
3
2

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
3
3