初めに
今どきのiAd実装 - Qiitaを拝見いたしまして、3日目で途切れるのも嫌だったので、急遽書かせていただきます。
仕事終わりに見て次の日空いてたら極力書こうかなと思っています。
全てはiOS Second Stage Advent Calendar 2015 - Qiitaのためです。
Advent Calendarに空きを作りたくないです。
本題
何書こうか迷いましたが、今回は iOSというよりは Swiftについて書きます。
書いていいか正直迷いましたが、書いてから怒られようと思います。
ということで Swiftのジェネリックを使って配列(Array
)をユニークにする方法を紹介します。
Set
使えばいいじゃんっていうのは許してください。
ジェネリックやらprotocol extension
っていうのに触れてみたかったんです。
ソースコード
できるだけ Swift2の記法に合わせたくて以下の形でできました。
import Foundation
extension SequenceType where Generator.Element: Equatable {
public func uniq() -> [Generator.Element] {
var result: [Generator.Element] = []
for element in self {
if !result.contains(element) {
result.append(element)
}
}
return result
}
}
let names = ["hoge", "fuga", "foo", "bar", "fuga"].uniq()
print("names = \(names)")
// names = ["hoge", "fuga", "foo", "bar"]
解説
Array
を拡張せずにSequenceType
を拡張しました。
SequeceType
についてですが、以下の記事がとってもわかりやすいので参考にしてみてください。
Swift - GeneratorとSequence - Qiita
おまけ
独自に組んだクラス(例えばAPIから取得したEntity)などで重複なしの配列に変えたい時があるかと思います。(自分がそうでしたので)
例えば以下のようなクラスを保持していたとします。
class Cat {
let name: String
init(name: String) {
self.name = name
}
}
ですが同じクラス(猫)の重複を削除したい場合(上記で言えば同じ名前を持つ猫を外したい)どうしましょうという話です。
答えは簡単でCat
クラスがEquatable
を継承すれば大丈夫です。
Equatable
Equatable
を継承すると同じ型同士を==
で評価できるように実装しなければなりません。
以下のようにします。
class Cat: Equatable {
let name: String
init(name: String) {
self.name = name
}
}
// これを実装します
func ==(lhs: Cat, rhs: Cat) -> Bool {
return lhs.name == rhs.name
}
上記のように実装すれば先ほど作成したuniq()
関数も使えます。
またswitch
文でのcase
での分岐でも使えるので結構重宝します。
終わりに
と短めではありますが、結構これをかけるようになった時にSwift
に近づけたなって思えたので紹介しました。
最後に僕の苦悩を紹介して、終わりにします。
アドベントカレンダー、登録少ないから書こうかな! https://t.co/NPr7BI2Gw0
— ryokosuge (@ryo_kosuge) 2015, 12月 2
@ryo_kosuge iOSと書いてあるけどSwiftの事書いて良いのかな...
— ryokosuge (@ryo_kosuge) 2015, 12月 2
@ryo_kosuge いいや、書いてから怒られよう
— ryokosuge (@ryo_kosuge) 2015, 12月 2
5分も悩んでませんでした。
以上になります。