LoginSignup
2
7

More than 3 years have passed since last update.

SwiftUIに向けて、サボり気味だったKeyPathのキャッチアップ

Posted at

SwiftUIではKeyPathが当たり前のように使われています。
中身を理解するのに、サボっていたKeyPathのキャッチアップをする必要が出てしまったのでやっていきます。

こちらの記事がわかり易かったので、ベース同じコードを引用させて頂いております。
https://qiita.com/BlueEventHorizon/items/dee0eb27fbba83ed8ea9

ソートを例にしたコード

KeyPathの便利さがめっちゃわかる.swift
import Foundation

enum SortOrder {
    case ascending
    case descending
}

extension Sequence {

    func sorted<T: Comparable>(by keyPath: KeyPath<Element, T>, order: SortOrder = .ascending) -> [Element] {
        return sorted { a, b in
            switch order {
            case .ascending:
                return a[keyPath: keyPath] < b[keyPath: keyPath]
            case .descending:
                return a[keyPath: keyPath] > b[keyPath: keyPath]
            }
        }
    }

}

struct User {
    var name: Name

    struct Name {
        var first: String
        var last: String
    }
}

let person1 = User(name: .init(first: "Yoshiharu", last: "Yamada"))
let person2 = User(name: .init(first: "Masahiro", last: "Tanaka"))

let people = [person1, person2]
let results = people.sorted(by: \.name.first)

KeyPathが便利となる動機

もしKeyPathがなかったらこのような処理が必要になります。

もしkeyPathがなかったら.swift
let people = [person1, person2]
let results = people.sorted { $0.name.first < $1.name.first }

たとえば、name.firstというキーで比較をしてほしい意図は明確なのに、クロージャを作らないといけませんし、同じプロパティのキーを2度書かないといけないのは面倒です。

これを一度指定すればいいようにできるのが、keyPathです。

sortedに対してkeypath指定をすればいいので

keyPath便利.swift
let results = people.sorted(by: \.name.first)
// let results = people.sorted(by: \User.name.first) でも可能

のように書けます。ファンタスティック!

KeyPathとは

KeyPath.swift
class KeyPath<Root, Value> : PartialKeyPath<Root>

で宣言されています。
今回は、KeyPath<User, String> となっています。

インスタンスにkeyPath経由でアクセス

sorted.swift
case .ascending:
    return a[keyPath: keyPath] < b[keyPath: keyPath]

上記のような辞書形式でアクセスします。キーは keyPath でないといけません。

感想

あるキーをつかって比較をする。のような場面ではわかりやすく便利になるのが分かりました。

SwiftUI楽しみですね!

2
7
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
2
7