Swift
エラー対処
swift4

【Swift4】キーが配列の辞書型のキーを、配列に取り出したい。(Cannot assign value of type 'Dictionary<String, NSArray>.Keys' to type '[String]'のエラー)

はじめに

理解と知識が激浅のため、誤った記述をしている可能性がございます。
ご了承ください。

やりたかったこと

キーが配列の辞書型のキーを、配列に取り出したい。(Swiftで)

objective-cで書くとこんな感じのこと

hoge.m
    NSDictionary* dic = @{@"キー1" : @[@"値A", @"値B", @"値C"],
                          @"キー2" : @[@"値A", @"値B", @"値C", @"値D"]
                          @"キー3" : @[@"値A", @"値B"],
                          @"キー4" : @[@"値A", @"値B"]
                         };

    NSArray* arr = [dic allKeys];

ディクショナリからキーだけの配列を取得するallKeysを使用。
(例)キー値配列の取得
引用:http://iphone-tora.sakura.ne.jp/nsdictionary.html

@property(readonly, copy) NSArray<KeyType> *allKeys;
引用:Apple Documentation allKeys

Swiftで書くとこんな感じだった

書き方①〜sortする〜

書き方①.swift
    var dic: [String: NSArray] = [:]
    var arr: [String] = []

    override func viewDidLoad() {
        super.viewDidLoad()
        dic = ["キー1" : ["値A", "値B", "値C"],
                        "キー1" : ["値A", "値B", "値C", "値D"],
                        "キー1" : ["値A", "値B"],
                        "キー1" : ["値A", "値B"]
        ]

        arr = menuSections.keys.sorted() // sorted()をくっつけないとエラー😱
}

SwiftもallKeysの役割と似たようなプロパティがあるのかと検索しましたが、
該当するものが見つかりませんでした。。。。orz
keys(objective-CのallKeysのノリ)だけだとエラーが出てしまってつまずきましたが、色々と調べたところ、
sorted()したところ、エラーCannot assign value of type 'Dictionary<String, NSArray>.Keys' to type '[String]'は解消されました。

Instance Method
sorted()
Returns the elements of the sequence, sorted.
引用:Apple Documentation sorted

日本語訳:シーケンスの要素を返して、並べます。(たぶん)

シーケンス(Sequence)とは

順番に並んだ一続きのデータや手順のことや、
並んだ順番にデータや手順を取り扱う処理方式などのこと
参考:http://e-words.jp/w/%E3%82%B7%E3%83%BC%E3%82%B1%E3%83%B3%E3%82%B9.html

しかし、もう少し調べたところ、
sortしなくても下記の方法でエラーが解消できる方法が見つかりました! 

書き方②〜イニシャライズする〜

書き方②.swift
    var dic: [String: NSArray] = [:]
    var arr: [String] = []

    override func viewDidLoad() {
        super.viewDidLoad()
        dic = ["キー1" : ["値A", "値B", "値C"],
                        "キー1" : ["値A", "値B", "値C", "値D"],
                        "キー1" : ["値A", "値B"],
                        "キー1" : ["値A", "値B"]
        ]
        arr = [String](dic.keys) // これ⭐️
    }

参考にさせていただいた記事です↓
Swift 3でDictionaryのキーだけの配列を作る

[String]でイニシャライズすればいいっぽい
(※Dictionaryでは順番は保証されません)

とのこと。

イニシャライズとは

最初の状態にすること(初期化の意味に近い)
参考:http://wa3.i-3-i.info/word16120.html

だそうです。
ただ、この方法だと並び方がよくわからない感じになっていたので、
普通にsortする①みたいな方法の方がいいのかな^^;(わからん)

ふわっとしたところがかたまり次第、追記していこうと思います・・・!

追記〜そもそもの問題点等〜

(2017/6/11更新ぶん)

会社の先輩から有り難いことに↑に関してコメントいただいたので、
教えていただいたことを元に、わからないことを調べつつ追記します(`・ω・´)

keysはCollection型

x-codeで、option+クリックでdescrition確認できる。
スクリーンショット 2018-06-11 1.36.47.png

Relationships Conforms To
Collection, Equatable
Swift Standard Liblaryより引用

そもそもkeysはCollection型なので、
var arr: [String] = []には型が違うので入れられない。

参考:CollectionTypeについて

スクリーンショット 2018-06-11 1.59.24.png
引用:https://docs.swift.org/swift-book/LanguageGuide/CollectionTypes.html

Array, Set, DictionaryはCollection Typesに準拠していることがわかりますね。Collection Typesに準拠したクラスは複数の明示された型のキーや値を格納することができ、それ以外の方を格納することは出来ません。つまり、キーや値の型を取得する際は、想定された型を受け取ることが保証できます。
引用:Swiftらしいコーディングを学ぶ 「CollectionType」
CollectionType Protocol Reference

ちなみにこれでも配列取れる。(親切にx-codeに書いてある)

ほげ.swift
        for k in dic.keys {
            print(k)
        }

だそうです(`・ω・´)←一応実行して確認した

sorted()は戻り値が[String]

func sorted() -> [String]

スクリーンショット 2018-06-11 1.32.24.png

これもx-codeが親切に教えてくれている・・・・
戻り値をちゃんと見よう(`・ω・´)

今後に向けた改善点

型をちゃんと意識すること
今まで細かく意識していなかった・・・w
これを意識するだけでも結構、躓き方がましになる気がする。

x-codeでdescritionとか確認してみよう
知りたいことが書いてあるかも。

swiftプログラミング言語ガイドを読もう!
読もう!(`・ω・´)

以上です。