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]