Swiftのディクショナリから特定のインデックスのキーを取得するにはどうすればよいですか?


114

私が持っているDictionaryスウィフトに、私は、特定のインデックスのキーを取得したいと思います。

var myDict : Dictionary<String,MyClass> = Dictionary<String,MyClass>()

キーを反復処理してログに記録できることを知っています

for key in myDict.keys{

    NSLog("key = \(key)")

}

しかし、不思議なことに、このようなことは不可能です

var key : String = myDict.keys[0]

どうして ?


11
ご存知のとおり、Swift辞書は特定の順序であるとは限りません。あなたは、キーは、あなたがそれらを置くために、インデックスを作成することを確実に期待することはできませんので。
radex

+1 @radexと、可能であれば、ステートメントについての詳細を読むためのソースを追加したい場合は、大歓迎です。
SH

回答:


191

これkeysLazyMapCollection<[Key : Value], Key>、を添え字として使用できないが返されるためIntです。これを処理する1つの方法はstartIndex、たとえば次のように添え字を付けたい整数で辞書を進めることです。

let intIndex = 1 // where intIndex < myDictionary.count
let index = myDictionary.index(myDictionary.startIndex, offsetBy: intIndex)
myDictionary.keys[index]

別の可能な解決策はkeys、入力として配列を初期化することです。その結果、結果に整数の添え字を使用できます。

let firstKey = Array(myDictionary.keys)[0] // or .first

辞書は本質的に順序付けられていないため、特定のインデックスのキーが常に同じであるとは期待しないでください。


3
Array(myDict)[0].0キー配列をコピーせず、ディクショナリの内部構造をコピーしてはならないので、おそらく高速です。
David Berry

5
どのキーが返されるかについては約束はありませんが、返される「ビュー」タイプについては十分に注意してください。実際の質問には当てはまらないため、私の回答を削除しました。
Rob Napier 14

9
Robが言っていることを明確にするために、キーは常に同じ順序で並べられているように見えるかもしれませんが、これはそうではなく、単に実装の詳細です。キー「foo」を追加できる可能性は非常に高く、内部表現は辞書を完全に並べ替えます。辞書は、キーと値のペアの順序付けられていないコレクションです。したがって、上記の答えは当てはまらない危険な仮定を行っています。
ジャックローレンス

8
特定の順序でキーが必要な場合は、それらの配列を保持してください。その後、それらをのように使用できますmyDict[keysArray[0]]
Zev Eisenberg 2014

1
動作しません...'NSDictionary' is not convertible to '_ArrayBuffer<T>'
Chris

53

Swift 3:Array()これを行うのに役立ちます。

キーを取得:

let index = 5 // Int Value
Array(myDict)[index].key

値を取得:

Array(myDict)[index].value

これは私にとってSwift 3で機能します。ただし、作成された配列がなぜ再配置されるのか理解できません。何かご意見は?
Slarty Bartfast、2017年

これは私を助けてくれてありがとう
ANE

1
@josef直観に反するのはどうですか?辞書はキーと値のペアであるため、インデックスの概念は修正されません。配列はインデックスによってアクセスされるため、これによりディクショナリが配列になり、そのインデックスによって配列にアクセスします。のようなディクショナリは["a": 1, "b": 2]、のようなディクショナリの配列に変換[[key: "a", value: 1], [key: "b", value: 2]]できます。これは、インデックスによってアクセスできます。
Peter R

29

以下は、インデックスによってディクショナリのキーと値にアクセスするための小さな拡張です。

extension Dictionary {
    subscript(i: Int) -> (key: Key, value: Value) {
        return self[index(startIndex, offsetBy: i)]
    }
}

3
'advance' APIはSwift 2.0で削除されましたuse --self [self.startIndex.advancedBy(i)]
Romain

2
@TomSawyer辞書は順序付けされていません。
ホセ・ラミレス

12

辞書を反復処理してfor-inでインデックスを取得し、列挙することができます(他の人が言ったように、以下のような順序で出力される保証はありません)

let dict = ["c": 123, "d": 045, "a": 456]

for (index, entry) in enumerate(dict) {
    println(index)   // 0       1        2
    println(entry)   // (d, 45) (c, 123) (a, 456)
}

最初に並べ替えたい場合

var sortedKeysArray = sorted(dict) { $0.0 < $1.0 }
println(sortedKeysArray)   // [(a, 456), (c, 123), (d, 45)]

var sortedValuesArray = sorted(dict) { $0.1 < $1.1 }
println(sortedValuesArray) // [(d, 45), (c, 123), (a, 456)]

その後、繰り返します。

for (index, entry) in enumerate(sortedKeysArray) {
    println(index)    // 0   1   2
    println(entry.0)  // a   c   d
    println(entry.1)  // 456 123 45
}

順序付けされた辞書を作成する場合は、ジェネリックスを調べる必要があります。


1
456に等しいインデックスを検索したい場合はどうなりますか?
Famic Tech 2018

2
@Max、これは古いSwift構文です。今すぐ使用できます: dict.enumerated().forEach { (index, element) in ... }
Matthew Korporaal

8

https://developer.apple.com/library/prerelease/ios/documentation/swift/conceptual/swift_programming_language/CollectionTypes.htmlから:

Arrayインスタンスを取得するAPIで辞書のキーまたは値を使用する必要がある場合は、keysまたはvaluesプロパティを使用して新しい配列を初期化します。

let airportCodes = [String](airports.keys) // airportCodes is ["TYO", "LHR"]   
let airportNames = [String](airports.values) // airportNames is ["Tokyo", "London Heathrow"]

5

SWIFT 3.最初の要素の例

let wordByLanguage = ["English": 5, "Spanish": 4, "Polish": 3, "Arabic": 2]

if let firstLang = wordByLanguage.first?.key {
    print(firstLang)  // English
}

3
キーがポーランド語であるインデックスを取得したい場合はどうなりますか?
Famic Tech 2018

5

スウィフト3指定されたインデックスのキー値ペア(タプル)を取得するには、このコードを使用してみてください:

extension Dictionary {
    subscript(i:Int) -> (key:Key,value:Value) {
        get {
            return self[index(startIndex, offsetBy: i)];
        }
    }
}

3

以下はSwift 1.2を使用した例です

var person = ["name":"Sean", "gender":"male"]
person.keys.array[1] // "gender", get a dictionary key at specific index 
person.values.array[1] // "male", get a dictionary value at specific index

3

SWIFT 4


少しトピックから外れています:しかし、辞書の配列 がある場合は次のようになります [[String:String]]

var array_has_dictionary = [ // Start of array

   // Dictionary 1

   [ 
     "name" : "xxxx",
     "age" : "xxxx",
     "last_name":"xxx"
   ],

   // Dictionary 2

   [ 
     "name" : "yyy",
     "age" : "yyy",
     "last_name":"yyy"
   ],

 ] // end of array


cell.textLabel?.text =  Array(array_has_dictionary[1])[1].key
// Output: age -> yyy

1
あなたの例で年齢= xxxxのアイテムのインデックスを取得するにはどうすればよいですか?
Famic Tech 2018

1
arrayIndex = 0、ageDictIndex = 1、Array(array_has_dictionary [arrayIndex] .keys)[ageDictIndex] = xxxx
Kristian

@FamicTech、クリスはあなたの質問に答えました
Suhaib '31

0

JavaのLinkedHashMapのようなものを探していました。SwiftもObjective-Cも、私が間違っていない限り、どちらも持っていません。

私の最初の考えは、私の辞書を配列でラップすることでした。[[String: UIImage]]しかし、辞書からキーを取得するのはおかしいことに気づき、Array(dict)[index].keyタプルを使いました。これで私の配列は次のようになり[(String, UIImage)]、で取得できますtuple.0。それを配列に変換する必要はもうありません。ちょうど私の2セント。

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.