LoginSignup
28
23

More than 5 years have passed since last update.

[Swift] 順序付き辞書、DictionaryLiteral

Last updated at Posted at 2017-04-02

前置き: Swift5における変更点

コメントで頂きましたが、DictionaryLiteralという名称はSwift5でDeprecatedとなり、KeyValuePairsにRenameされました。(@imaizumeさんありがとうございます!)

PRを見た感じだと完全にRenameだけで機能は変わっていないようです。
DictionaryでもLiteralでもないバッドネーミングだから変えたとのこと。

この記事はSwift3時点で書かれたものなので、以降DictionaryLiteralと古い呼称で記述しておりますがご容赦ください。

DictionaryLiteralとは

SwiftのDictionaryはハッシュテーブルなので、素早いルックアップが可能ですが、イテレートした際に順序が保証されません

let dict = ["0": 0, "1": 1, "2": 2, "3": 3]
for (key, value) in dict {
    print("\(key), \(value)")
}

出力はこうなります。

2, 2
1, 1
0, 0
3, 3

順番がバラバラになりました。

では、どうしても辞書の順序を保存しておきたいときはどうしたら良いでしょうか。実は、順序付きの辞書は用意されています。

DictionaryLiteralというのがそれです。ExpressibleByDictionaryLiteralに準拠しているため、型を明示すれば辞書のリテラルをそのまま代入できます。

let dict: DictionaryLiteral = ["0": 0, "1": 1, "2": 2, "3": 3]
for (key, value) in dict {
    print("\(key), \(value)")
}
0, 0
1, 1
2, 2
3, 3

順番が保たれています。また、DictionaryLiteralはRandomAccessCollectionなので、配列のように添え字アクセスすることも可能です。キーとバリューのタプルが返ってきます。

print(dict[1])
("1", 1)

ただし、DictionaryLiteralはDictionaryと同じように使えるわけではありません。残念ながら、少なくとも機能的な面では、DictionaryLiteralは[(String, Int)]のようにタプルの配列を書くのとほとんど変わりません。

例えば、キーを指定して値を取得することはできません。指定したキーに対応する値を取得するにはこのようにします。

let dict: DictionaryLiteral = ["0": 0, "1": 1, "2": 2, "3": 3]
if let index = dict.index(where: { $0.0 == "1" }) {
  let value = dict[index].1
  print("value: \(value)") // value: 1
}

また、同じキーが複数ある状態も許容してしまいます。

var dict: DictionaryLiteral = ["0": 0, "0": 1, "0": 2, "0": 3]
if let index = dict.index(where: { $0.0 == "1" }) {
  let value = dict[index].1
  print("value: \(value)") // value: 1
}

ではどういう時にDictionaryLiteralを使うと良いのでしょうか。ドキュメントにはこうあります。

Use a Dictionary​Literal instance when you need an ordered collection of key-value pairs and don’t require the fast key lookup that the Dictionary type provides.

  • 順序つき辞書が必要なとき
  • 高速なルックアップが不要なとき

メリットとしては名前の通り、Dictionaryのリテラルで書けて可読性が上がるということなどでしょうか。順序付きの辞書が欲しくなったときに、検討してみてはいかがでしょうか。


:whale2: Twitter: @a_beco
:guitar: SoundCloud: @beco <- 作業用BGMにどうぞ!

28
23
4

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
28
23