前書
なんだか最近は関数が熱いですね! (すっとぼけ)
個人的に復習用の一覧が欲しかったので、コンパクトさ重視で雑にまとめました。リンクも解説もありません。ただし解説記事を見た覚えのない関数については、ごく簡単な「使い方メモ」を付けています。
ここに書いてある内容はすべて、Xcode利用時に import Swift と書いて、Swiftのところをコマンド押しながらクリックすれば見つかります。詳しくはそちらをご覧ください。
2015.04.16 アップデート
Swift 1.2 ですよ、プロ… プログラマーさん!
- 廃止: countElement
- 追加
- flatMap <- 値を扱う / 取り出す
- zip <- 構造体をつくる
- isUniquelyReferenced他 <- 値を扱う / 調べる
- unsafeUnwrap <- レガシーAPIを扱う
- @noescape, @inline などの新機能実装を反映
メモ
- flatMapは便利。zipは… どうなんでしょう?
- isUniquelyReferencedは「コピーオンライトを最適化するとき超便利」だそうです
- 参照元には「countの計算量はO(1)の場合と O(N) の場合がある」というようなことがサラっと書いてあるため注意が必要
- 今回も「説明は読んだけど使い方が分からなかった関数」が最後にあります
- (extend, splice の where がよく分からない)
テキストを出力する
- 標準出力に書き込む
@inline(never) func print<T>(value: T)
@inline(never) func println<T>(value: T)
@inline(never) func println()
- 任意の出力先に書き込む
@inline(never) func print<T, TargetStream : OutputStreamType>(value: T, inout target: TargetStream)
@inline(never) func println<T, TargetStream : OutputStreamType>(value: T, inout target: TargetStream)
- テキストを得る
@inline(never) func toString<T>(x: T) -> String
- ダンプする (デバッグプリントよりも仕様の勉強になる)
func dump<T>(x: T, name: String? = default, indent: Int = default, maxDepth: Int = default, maxItems: Int = default) -> T
func dump<T, TargetStream : OutputStreamType>(x: T, inout targetStream: TargetStream, name: String? = default, indent: Int = default, maxDepth: Int = default, maxItems: Int = default) -> T
デバッグする
- 無条件で落とす
@inline(__always) func assertionFailure(_ message: @autoclosure () -> String = default, file: StaticString = default, line: UWord = default)
@noreturn func fatalError(_ message: @autoclosure () -> String = default, file: StaticString = default, line: UWord = default)
@noreturn func preconditionFailure(_ message: @autoclosure () -> String = default, file: StaticString = default, line: UWord = default)
- クロージャがfalseを返したら落とす
func assert(condition: @autoclosure () -> Bool, _ message: @autoclosure () -> String = default, file: StaticString = default, line: UWord = default)
func precondition(condition: @autoclosure () -> Bool, _ message: @autoclosure () -> String = default, file: StaticString = default, line: UWord = default)
- 標準出力に情報を出す
@inline(never) func debugPrint<T>(x: T)
@inline(never) func debugPrintln<T>(x: T)
- 任意の出力先に情報を出す
@inline(never) func debugPrint<T, TargetStream : OutputStreamType>(value: T, inout target: TargetStream)
@inline(never) func debugPrintln<T, TargetStream : OutputStreamType>(x: T, inout target: TargetStream)
- デバッグ用のテキストを得る
func toDebugString<T>(x: T) -> String
値を扱う
- 値を入れ替える
func swap<T>(inout a: T, inout b: T)
- ミラーを作る (?)
func reflect<T>(x: T) -> MirrorType
- オブジェクトのライフタイムを延長しつつ関数を実行する
func withExtendedLifetime<T, Result>(x: T, f: @noescape () -> Result) -> Result
func withExtendedLifetime<T, Result>(x: T, f: @noescape T -> Result) -> Result
調べる
- 前者が後者を含むか調べる
func contains<S : SequenceType where S.Generator.Element : Equatable>(seq: S, x: S.Generator.Element) -> Bool
func contains<S : SequenceType, L : BooleanType>(seq: S, predicate: @noescape (S.Generator.Element) -> L) -> Bool
- 同じものが同じ順番で並んでいるか調べる
func equal<S1 : SequenceType, S2 : SequenceType where S1.Generator.Element == S1.Generator.Element, S1.Generator.Element : Equatable>(a1: S1, a2: S2) -> Bool
func equal<S1 : SequenceType, S2 : SequenceType where S1.Generator.Element == S1.Generator.Element>(a1: S1, a2: S2, isEquivalent: @noescape (S1.Generator.Element, S1.Generator.Element) -> Bool) -> Bool
- 前者の冒頭が後者と同じか調べる
func startsWith<S0 : SequenceType, S1 : SequenceType where S0.Generator.Element == S0.Generator.Element>(s: S0, prefix: S1, isEquivalent: @noescape (S0.Generator.Element, S0.Generator.Element) -> Bool) -> Bool
func startsWith<S0 : SequenceType, S1 : SequenceType where S0.Generator.Element == S0.Generator.Element, S0.Generator.Element : Equatable>(s: S0, prefix: S1) -> Bool
- 辞書において前者が先にあるか調べる
func lexicographicalCompare<S1 : SequenceType, S2 : SequenceType where S1.Generator.Element == S1.Generator.Element>(a1: S1, a2: S2, isOrderedBefore less: @noescape (S1.Generator.Element, S1.Generator.Element) -> Bool) -> Bool
func lexicographicalCompare<S1 : SequenceType, S2 : SequenceType where S1.Generator.Element == S1.Generator.Element, S1.Generator.Element : Comparable>(a1: S1, a2: S2) -> Bool
// 使い方メモ
lexicographicalCompare("a", "z") // -> true
lexicographicalCompare("z", "a") // -> false
// …何に使えばいいんだろう?
- 2つのレンジに重複があるか調べる
func overlaps<I0 : IntervalType, I1 : IntervalType where I0.Bound == I0.Bound>(lhs: I0, rhs: I1) -> Bool
- 空かどうか調べる
func isEmpty<C : CollectionType>(x: C) -> Bool
- よそで参照されているか調べる
func isUniquelyReferenced<T : NonObjectiveCBase>(inout object: T) -> Bool
func isUniquelyReferencedNonObjC<T>(inout object: T?) -> Bool
// 使い方メモ
数える
- 2つの引数の間を数える
- それ以外のものを数える
func distance<T : ForwardIndexType>(start: T, end: T) -> T.Distance
func count<T : _CollectionType>(x: T) -> T.Index.Distance
- 有効なレンジを求める
func indices<C : CollectionType>(x: C) -> Range<C.Index>
// 使い方メモ
indices("hello, world!") // -> 0..<13
取り出す
※ コメント欄参照
- Optionalから取り出して処理する (Haskell で言えば fmap)
func map<T, U>(x: T?, f: @noescape (T) -> U) -> U?
func flatMap<T, U>(x: T?, f: @noescape (T) -> U?) -> U?
- 1つずつ取り出して処理する
func map<C : CollectionType, T>(source: C, transform: (C.Generator.Element) -> T) -> [T]
func map<S : SequenceType, T>(source: S, transform: (S.Generator.Element) -> T) -> [T]
func flatMap<S : SequenceType, T>(source: S, transform: @noescape (S.Generator.Element) -> [T]) -> [T]
func flatMap<C : CollectionType, T>(source: C, transform: (C.Generator.Element) -> [T]) -> [T]
- 1つずつ取り出す (数字付き)
func enumerate<Seq : SequenceType>(base: Seq) -> EnumerateSequence<Seq>
// 使い方メモ
for (n, s) in enumerate("Swift") {
println("letter at \(n) is \(s)")
}
// 結果はこうなる
// letter at 0 is S
// letter at 1 is w
// letter at 2 is i
// letter at 3 is f
// letter at 4 is t
数値を扱う
- 絶対値を返す
func abs<T : SignedNumberType>(x: T) -> T
- nだけ増やす
- nだけ増やす (上限あり)
func advance<T : ForwardIndexType>(start: T, n: T.Distance) -> T
func advance<T : ForwardIndexType>(start: T, n: T.Distance, end: T) -> T
- 最大値を求める
func max<T : Comparable>(x: T, y: T, z: T, rest: T...) -> T
func max<T : Comparable>(x: T, y: T) -> T
func maxElement<R : SequenceType where R.Generator.Element : Comparable>(elements: R) -> R.Generator.Element
- 最小値を求める
func min<T : Comparable>(x: T, y: T) -> T
func min<T : Comparable>(x: T, y: T, z: T, rest: T...) -> T
func minElement<R : SequenceType where R.Generator.Element : Comparable>(elements: R) -> R.Generator.Element
- 数字のデータ型を変換する
func numericCast<T : _UnsignedIntegerType, U : _SignedIntegerType>(x: T) -> U
func numericCast<T : _SignedIntegerType, U : _UnsignedIntegerType>(x: T) -> U
func numericCast<T : _UnsignedIntegerType, U : _UnsignedIntegerType>(x: T) -> U
func numericCast<T : _SignedIntegerType, U : _SignedIntegerType>(x: T) -> U
// 使い方メモ
// 正直よく分からない
// レガシーなAPIにありがちな引数、変換が必要でめんどくさい
func f(x: Int32) {
println("Int32 x is \(x)")
}
func g(x: Int) {
// Int32が必要なので、勝手にInt32にしてくれる (ようだ)
f(numericCast(x))
}
// Int32(x) などと書かずに使える
g(10)
文字列・配列などを扱う
- 後ろにくっつける
func extend<C : RangeReplaceableCollectionType, S : CollectionType where C.Generator.Element == C.Generator.Element>(inout x: C, newElements: S)
- n番目に挿入する
- n番目に継ぎ合せる
func insert<C : RangeReplaceableCollectionType>(inout x: C, newElement: C.Generator.Element, atIndex i: C.Index)
func splice<C : RangeReplaceableCollectionType, S : CollectionType where C.Generator.Element == C.Generator.Element>(inout x: C, newElements: S, atIndex i: C.Index)
// 使い方メモ
var arr = [1,2,3,4,5]
insert(&arr, 100, atIndex: 2) // -> [1, 2, 100, 3, 4, 5]
splice(&arr, [200], atIndex: 2) // -> [1, 2, 200, 100, 3, 4, 5]
切り出す
- 先頭のモノを切り出す
- 最後のモノを切り出す
func first<C : CollectionType>(x: C) -> C.Generator.Element?
func last<C : CollectionType where C.Index : BidirectionalIndexType>(x: C) -> C.Generator.Element?
- 先頭から最大n個を切り出す
- 最後から最大n個を切り出す
func prefix<S : Sliceable>(s: S, maxLength: Int) -> S.SubSlice
func suffix<S : Sliceable where S.Index : BidirectionalIndexType>(s: S, maxLength: Int) -> S.SubSlice
取り除く
- 最初だけ取り除いたものをつくる
- 最後だけ取り除いたものをつくる
func dropFirst<Seq : Sliceable>(s: Seq) -> Seq.SubSlice
func dropLast<S : Sliceable where S.Index : BidirectionalIndexType>(s: S) -> S.SubSlice
- 最後のモノを取り除く
- インデックスで取り除く
- レンジで取り除く
- 全て取り除く
func removeLast<C : RangeReplaceableCollectionType where C.Index : BidirectionalIndexType>(inout x: C) -> C.Generator.Element
func removeAtIndex<C : RangeReplaceableCollectionType>(inout x: C, index: C.Index) -> C.Generator.Element
func removeRange<C : RangeReplaceableCollectionType>(inout x: C, subRange: Range<C.Index>)
func removeAll<C : RangeReplaceableCollectionType>(inout x: C, keepCapacity: Bool = default)
並べ替える
- 順番を逆にする
func reverse<C : CollectionType where C.Index : BidirectionalIndexType>(source: C) -> [C.Generator.Element]
- ソートする
func sort<T : Comparable>(inout array: ContiguousArray<T>)
func sort<T : Comparable>(inout array: [T])
func sort<C : MutableCollectionType where C.Index : RandomAccessIndexType, C.Generator.Element : Comparable>(inout collection: C)
- クロージャの条件でソートする
func sort<T>(inout array: ContiguousArray<T>, isOrderedBefore: (T, T) -> Bool)
func sort<T>(inout array: [T], isOrderedBefore: (T, T) -> Bool)
func sort<C : MutableCollectionType where C.Index : RandomAccessIndexType>(inout collection: C, isOrderedBefore: (C.Generator.Element, C.Generator.Element) -> Bool)
- ソートしたものを作る
func sorted<C : SequenceType where C.Generator.Element : Comparable>(source: C) -> [C.Generator.Element]
func sorted<C : SequenceType>(source: C, isOrderedBefore: (C.Generator.Element, C.Generator.Element) -> Bool) -> [C.Generator.Element]
探す・絞り込む
- 先頭から順番に探していき、インデックスを調べる
func find<C : CollectionType where C.Generator.Element : Equatable>(domain: C, value: C.Generator.Element) -> C.Index?
- 配列などにフィルターをかけて絞り込む
func filter<S : SequenceType>(source: S, includeElement: (S.Generator.Element) -> Bool) -> [S.Generator.Element]
1つに減らす・区切って増やす
- セパレーターを間に入れてつなげる
func join<C : ExtensibleCollectionType, S : SequenceType where C == C>(separator: C, elements: S) -> C
- 要素を1つずつ処理して減らす
func reduce<S : SequenceType, U>(sequence: S, initial: U, combine: @noescape (U, S.Generator.Element) -> U) -> U
- 該当部分で区切って配列にする
// 引数の順番が変更された
func split<S : Sliceable, R : BooleanType>(elements: S, maxSplit: Int = default, allowEmptySlices: Bool = default, #isSeparator: @noescape (S.Generator.Element) -> R) -> [S.SubSlice]
構造体をつくる
- 等差数列みたいな構造体をつくる
func stride<T : Strideable>(from start: T, through end: T, by stride: T.Stride) -> StrideThrough<T>
func stride<T : Strideable>(from start: T, to end: T, by stride: T.Stride) -> StrideTo<T>
// 使い方メモ
// through だと100まで、toだと98まで
// これさえ作っておけば…
var srd = stride(from: 0, through: 100, by: 2).generate()
// どんどん出せるよ!
srd.next()! // -> 0
srd.next()! // -> 2
srd.next()! // -> 4
srd.next()! // -> 6
srd.next()! // -> 8
- レイジーコレクションをつくる
func lazy<S : SequenceType>(s: S) -> LazySequence<S>
func lazy<S : CollectionType where S.Index : ForwardIndexType>(s: S) -> LazyForwardCollection<S>
func lazy<S : CollectionType where S.Index : BidirectionalIndexType>(s: S) -> LazyBidirectionalCollection<S>
func lazy<S : CollectionType where S.Index : RandomAccessIndexType>(s: S) -> LazyRandomAccessCollection<S>
//使い方メモ
// lazy() を使ってレイジーコレクション系の構造体をつくる
// つくるだけで、実際の処理はしない
let lazyMap = lazy(Array(count: 1000000, repeatedValue: 0)).map {
num -> Int in
return num + 10
} // -> LazyRandomAccessCollection<MapCollectionView<[Int], Int>>
// クロージャ内の処理が一度だけ行われる
lazyMap[999999] // -> 10
- ZIPでくれる構造体をつくる
func zip<S0 : SequenceType, S1 : SequenceType>(s0: S0, s1: S1) -> Zip2<S0, S1>
//使い方メモ
// "swift zip" で検索すると「zipでくれ」のzipによるノイズが結構ひどいです
let x = [1, 2, 3]
let y = ["a", "b", "c", "d"]
var z = zip(x, y).generate()
while let v = z.next() {
println(v.0) // -> 1 2 3
println(v.1) // -> a b c
}
メモリーについて調べる
- 最小アライメントを調べる
func alignof<T>(_: T.Type) -> Int
func alignofValue<T>(_: T) -> Int
- メモリーフットプリントを調べる
func sizeof<T>(_: T.Type) -> Int
func sizeofValue<T>(_: T) -> Int
- メモリー上の最小間隔を調べる (?)
func strideof<T>(_: T.Type) -> Int
func strideofValue<T>(_: T) -> Int
レガシーAPIを扱う
※ そこかしこに「危険」「注意」「タイプセーフが台無し」と書かれているアダルトな関数のみなさんです。
- ポインターを得る
func unsafeAddressOf(object: AnyObject) -> UnsafePointer<Void>
- ビット群を強引にキャストする
- オブジェクトを強引にダウンキャストする
- オプショナル値を強引にアンラップする
func unsafeBitCast<T, U>(x: T, _: U.Type) -> U
func unsafeDowncast<T>(x: AnyObject) -> T
@inline(__always) func unsafeUnwrap<T>(nonEmpty: T?) -> T
- ポインターを渡してクロージャを実行する (ObjC APIに便利)
// ミュータブル
func withUnsafeMutablePointer<T, Result>(inout arg: T, body: @noescape UnsafeMutablePointer<T> -> Result) -> Result
func withUnsafeMutablePointers<A0, A1, Result>(inout arg0: A0, inout arg1: A1, body: @noescape (UnsafeMutablePointer<A0>, UnsafeMutablePointer<A1>) -> Result) -> Result
func withUnsafeMutablePointers<A0, A1, A2, Result>(inout arg0: A0, inout arg1: A1, inout arg2: A2, body: @noescape (UnsafeMutablePointer<A0>, UnsafeMutablePointer<A1>, UnsafeMutablePointer<A2>) -> Result) -> Result
// イミュータブル
func withUnsafePointer<T, Result>(inout arg: T, body: @noescape UnsafePointer<T> -> Result) -> Result
func withUnsafePointers<A0, A1, Result>(inout arg0: A0, inout arg1: A1, body: @noescape (UnsafePointer<A0>, UnsafePointer<A1>) -> Result) -> Result
func withUnsafePointers<A0, A1, A2, Result>(inout arg0: A0, inout arg1: A1, inout arg2: A2, body: @noescape (UnsafePointer<A0>, UnsafePointer<A1>, UnsafePointer<A2>) -> Result) -> Result
廃止された関数
// countに統合
func count<I : RandomAccessIndexType>(r: Range<I>) -> I.Distance
func countElements<T : _CollectionType>(x: T) -> T.Index.Distance
// 引数の順序が変更
func split<S : Sliceable, R : BooleanType>(elements: S, isSeparator: (S.Generator.Element) -> R, maxSplit: Int = default, allowEmptySlices: Bool = default) -> [S.SubSlice]
// 引数がoutput -> inout output (参照渡し) に変更
func transcode<Input : GeneratorType, Output : SinkType, InputEncoding : UnicodeCodecType, OutputEncoding : UnicodeCodecType where InputEncoding.CodeUnit == InputEncoding.CodeUnit, OutputEncoding.CodeUnit == OutputEncoding.CodeUnit>(inputEncoding: InputEncoding.Type, outputEncoding: OutputEncoding.Type, input: Input, output: Output, #stopOnError: Bool) -> (Bool)
説明を読んでも分からなかった関数
/// Returns a `CVaListPointer` built from `args` that's backed by
/// autoreleased storage.
///
/// .. Warning:: This function is best avoided in favor of
/// `withVaList`, but occasionally (i.e. in a `class` initializer) you
/// may find that the language rules don't allow you to use
/// `withVaList` as intended.
func getVaList(args: [CVarArgType]) -> CVaListPointer
/// Re-order the given `range` of `elements` and return a pivot index
/// *p*. Postcondition: for all *i* in `range.startIndex..<`\ *p*,
/// and *j* in *p*\ `..<range.endIndex`, `less(elements[`\ *i*\ `],
/// elements[`\ *j*\ `]) && !less(elements[`\ *j*\ `], elements[`\
/// *p*\ `])`. Only returns `range.endIndex` when `elements` is
/// empty.
/// Requires: `isOrderedBefore` is a `strict weak ordering
/// <http://en.wikipedia.org/wiki/Strict_weak_order#Strict_weak_orderings>`__
/// over `elements`.
func partition<C : MutableCollectionType where C.Index : RandomAccessIndexType>(inout elements: C, range: Range<C.Index>, isOrderedBefore: (C.Generator.Element, C.Generator.Element) -> Bool) -> C.Index
/// Re-order the given `range` of `elements` and return a pivot index
/// *p*. Postcondition: for all *i* in `range.startIndex..<`\ *p*,
/// and *j* in *p*\ `..<range.endIndex`, `less(elements[`\ *i*\ `],
/// elements[`\ *j*\ `]) && !less(elements[`\ *j*\ `], elements[`\
/// *p*\ `])`. Only returns `range.endIndex` when `elements` is
/// empty.
/// Requires: The less-than operator (`func <`) defined in the `Comparable`
/// conformance is a `strict weak ordering
/// <http://en.wikipedia.org/wiki/Strict_weak_order#Strict_weak_orderings>`__
/// over `elements`.
func partition<C : MutableCollectionType where C.Index : RandomAccessIndexType, C.Generator.Element : Comparable>(inout elements: C, range: Range<C.Index>) -> C.Index
/// Translate `input`, in the given `InputEncoding`, into `output`, in
/// the given `OutputEncoding`.
///
/// :param: `stopOnError` causes encoding to stop when an encoding
/// error is detected in `input`, if `true`. Otherwise, U+FFFD
/// replacement characters are inserted for each detected error.
func transcode<Input : GeneratorType, Output : SinkType, InputEncoding : UnicodeCodecType, OutputEncoding : UnicodeCodecType where Input.Element == Input.Element, Output.Element == Output.Element>(inputEncoding: InputEncoding.Type, outputEncoding: OutputEncoding.Type, input: Input, inout output: Output, #stopOnError: Bool) -> Bool
/// Return an underestimate of the number of elements in the given
/// sequence, without consuming the sequence. For Sequences that are
/// actually Collections, this will return countElements(x)
func underestimateCount<T : SequenceType>(x: T) -> Int
/// Invoke `f` with a C `va_list` argument derived from `builder`.
func withVaList<R>(builder: VaListBuilder, f: @noescape CVaListPointer -> R) -> R
/// Invoke `f` with a C `va_list` argument derived from `args`.
func withVaList<R>(args: [CVarArgType], f: @noescape CVaListPointer -> R) -> R