文字列を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
)」へ同じ処理を施してくれるのですね。
###参考文献