Edited at

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

More than 1 year has passed since last update.


はじめに

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

ご了承ください。


やりたかったこと

キーが配列の辞書型のキーを、配列に取り出したい。(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プログラミング言語ガイドを読もう!

読もう!(`・ω・´)

以上です。