NSBlogger

意識高いブログ

Swiftの文字列操作まとめ

空文字のチェック

isEmpty」を使えばOK。空ならtrueが返ってきます。

var empty = ""
var empty2 = String()

//Empty.
if empty.isEmpty{
    println("Empty.")
}else{
    println("Not Empty.")
}

//Empty.
if empty2.isEmpty{
    println("Empty.")
}else{
    println("Not Empty.")
}

文字列の連結

+」でつなげてあげるだけ。
NSMutableString使ったり、[NSString stringWithFormat:@"%@%@", str1, str2] こんなことしなくていい!

var greeting = "Hello "
let name = "Tom"
greeting + name //Hello Tom

文字列を一文字ずつ取り出す

for in で取り出すと一文字ずつ取り出せます。楽ちん。

for char in "Hello!"{
    println(char)
}

print文内で変数を使う

バックスラッシュとカッコで囲んであげると変数が差し込めます。
日本語キーボード使ってるかたは、option + ¥マークでバックスラッシュ入力できます。

let name2 = "Tom"
println("Hello \(name2).") //Hello Tom.
println("1たす2は\(1+2)") //1たす2は3

文字数をカウントする

countElements」というメソッドに文字列を渡してあげると、文字数が返ってきます(Int)。

let longMessage = "こんにちは。今日は天気がいいです。"
countElements(longMessage) //17

文字列が等しいかどうか比較する

==」で比較できます。

var str1 = "こんにちは"
var str2 = "こんばんは"

if str1 == str2 {
    println("同じ文字列")
}else{
    println("違う文字列") //こちら。
}

str2 = "こんにちは"

if str1 == str2 {
    println("同じ文字列") //こちら。
}else{
    println("違う文字列")
}

文頭/文末に特定の文字列が含まれているか確認する

hasPrefix」を使うと文頭に含まれているかどうかをチェックできます。
hasSuffix」を使うと文末に含まれているかどうかをチェックできます。

var greetings = ["おはよう", "こんにちは", "こんばんは"]
for message in greetings {
    if message.hasPrefix("こん") {
        println(message) //こんにちは, こんばんは
    }
    if message.hasSuffix("ちは"){
        println(message) //こんにちは
    }
}

アルファベットを大文字/小文字にする

uppercaseString」で大文字に、「lowercaseString」で小文字にできます。

let lowerStr = "hello"
lowerStr.uppercaseString //HELLO

let upperStr = "HELLO"
upperStr.lowercaseString //hello


いろいろ便利になってますね。

Swiftの「Optional Value」の使い方

Optional Value

Swiftのコードを読んでいると変数の横に「?」や「!」がついていることがあります。
この「?」がついているものが「Optional Value」になります。

Optional Value の特徴

Optional Valueは「nil」を許容します。
逆にOptional Valueでないものは「nil」を許容しません。

Optional Value の宣言

var optionalValue:String? = "オプショナルです"

型の横に「?」をつけるだけです。
これでnilも代入可能なString型のオブジェクト完成です。

var normalValue:String = "オプショナルじゃない"
normalValue = nil //error

var optionalValue:String? = "オプショナルです"
optionalValue = nil //OK

実際は、Optional<Int>のような型宣言になりますが、「?」をつけるだけでOKです。

nilを許容していないオブジェクトに対してnilを代入しようと、「Could not find an overload for '__conversion' that accepts the supplied arguments」というエラーがでます。

Optional Value を代入するときの注意

Optionalじゃない変数にOptional Valueを代入しようとすると、エラーになります。

let number = "123"
let convertedNumber = number.toInt()

var intNumber:Int = convertedNumber //エラー

Value of optional type 'Int' not unwrapped; did you mean to use '!' or '?' ?」というエラーがでます。
「toInt()」でString型をInt型に変換できます。たとえば上記のような"123"はInt型に正しく変換できますが、"Hello, world"などの文字列はInt型に変換できませんよね。そんな場合はnilとして変換されます。
つまり、toInt()で変換された変数は「nilであるかもしれない」のでOptional Valueとなります。

Optional Valueを代入したいときは、代入先をOptionalにしてあげればOKです。

let number = "123"
let convertedNumber = number.toInt()

var intNumber:Int? = convertedNumber //OK

nilを許容しない変数にOptional Valueを代入したいときはどうすればよいでしょうか。

そこで、オブジェクトが必ずnilじゃない保証があるという前提で、「このオブジェクトはnilではありませんよ」と明示的に宣言するために「!」を使います。

let number = "123"
let convertedNumber = number.toInt()

var intNumber:Int = convertedNumber! //OK  convertedNumberはnilじゃない!

実際はImplicitlyUnwrappedOptional<Int>型になっているようです。

Optionalかどうかを判定する

Optionalかどうかを判定して条件分岐したいときは下記のようにするとよいです。

let number = "123"
let convertedNumber = number.toInt()

if let actualNumber = convertedNumber {
    println("\(actualNumber)はnilじゃないです。")
}else{
    println("nilでした。")
}

まとめ

Objective Cだとnilになっても普通に処理が走ることがありましたが、「?」「!」を使うことでコードを実行する前に「nilをどう扱うか」を制御することができるようになりました。

Swiftの「タプル(Tuple)」で複数のオブジェクトをひとまとめにする

タプル(Tuple)

タプルは複数のオブジェクトをまとめて扱えるものです。

タプルの例

let Blog = (20140608, "About tuple")

「20140608」「"About touple"」をもつBlogオブジェクトができました。
Blogオブジェクトへのアクセスの仕方はこちら。

Blog.0 //20140608
Blog.1 //"About tuple"

配列のように順番にアクセスできます。

要素に名前をつける

下記のようにすると、別の変数にまとめて代入できます。

var (date, article) = Blog
date    //20140608
article //"About tuple"

必要な要素のみ代入したいときはアンダースコアを使います。

var (date, _) = Blog
date    //20140608
_         //アンダースコアを指定すると、Xcode落ちました


最初に定義する際、それぞれの要素に意味を持たせると使いやすくなります。

let Blog = (date:20140608, article:"About tuple")
Blog.date    //20140608
Blog.article //About tuple

公式ドキュメントでは、Httpのステータスコードとステータスメッセージをもつオブジェクトを作っていました。
定数を宣言しそこに複数の意味を持たせたいときに使えそうです。

SwiftでArrayの中身を昇順・降順でソートする

Sort関数

「Sort」を使えば簡単に配列の中身を並び替えられます。

昇順

var numbers = [1,4,2,3,6,5]

sort(numbers)

numbers // [1,2,3,4,5,6]

そのままsortで配列を引数に与えてあげればOK。
引数の中身がソートされ、上書きされます。

var strings = ["a", "e", "d", "b", "c"]

sort(strings)

strings  // ["a", "b", "c", "d", "e"]

文字列もこの通り。

降順

下記で降順に並び替えられます

numbers = [1,4,2,3,6,5]

sort(numbers){$0 > $1}

numbers // [6,5,4,3,2,1]

クロージャを使ったSortの真面目な書き方

長々と書く

上記のようにSort関数は書けますが、実際は下記のようなクロージャを使った書き方になります。

strings = ["a", "e", "d", "b", "c"]

sort(strings){
    (str1 : String, str2 : String) -> Bool in
    return str1 > str2
}

strings // ["e", "d", "c", "b", "a"]

第一引数と第二引数を比較して、Boolを返してます。
returnの比較を逆転させればソートも逆になります。

型の省略

しかし、そもそも与えられた配列の中身を取り出して比較しているので、
引数および戻り値の型は明示的に指定しなくても推測されます。
したがって、下記のように省略が可能。

sort(strings){
    (str1, str2) in
    return str1 > str2
}

引数の型「String」と戻り値の型「Bool」を省略しました。

returnの省略

さらに、引数の()やreturnも省略できます。
今回の場合は、returnが一つに限定されているので、省略が可能。

sort(strings){ str1, str2 in str1 > str2 }

改行も除けばこのとおり、すっきりした形になります。

引数を$0, $1, ... に

そして、自分自身を引数としてとる場合、「str1」「str2」は「$0」「$1」などで置き換えることが可能です。

sort(strings){$0 > $1}

どうやら、「$0」や「$1」を使うときは「in」を省略できるようです。
めでたく、最初に書いた短いコードに辿りつけました。

SwiftのArrayがもつ非破壊的メソッド「map」

var numbers:Array<Int> = [0,2,4,6,8]
var doubleNumbers:Array<Int> = numbers.map({
    (number:Int) -> Int in
    return number * 2
    })

numbers
doubleNumbers

結果はこちら

[0,2,4,6,8]
[0,4,8,12,16]

numbersから値をひとつずつとってきて2倍したものを返してます。
非破壊的なので、元のnumbersには変化なし。(クロージャですね)

構文はこんな感じです。

(配列).map({
          (配列の要素:要素の型) -> 戻り値の型 in
          
          /*処理*/
          
          return 戻り値
})


また、下記のように短く書くこともできます。

var halfNumbers = numbers.map({numbers in numbers/2})

numbers
halfNumbers
[0,2,4,6,8]
[0,1,2,3,4]