Swift의 Dictionary에서 특정 인덱스의 키를 어떻게 얻습니까?


114

나는 DictionarySwift에 있고 특정 색인에서 키를 얻고 싶습니다.

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

그 이유 keys는 returns LazyMapCollection<[Key : Value], Key>이며 Int. 이를 처리하는 한 가지 방법 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
이것이 어떤 키를 반환할지에 대한 약속은 없지만 반환되는 "view"유형에 대한 좋은 메모입니다. 실제로 질문에 적용되지 않았기 때문에 내 답변을 삭제했습니다.
Rob Napier

9
Rob의 말을 명확히하기 위해 키가 매번 동일하게 주문되는 것처럼 보일있지만 이는 사실이 아니며 단순히 구현 세부 사항입니다. "foo"키를 추가하면 내부 표현이 딕셔너리를 완전히 재정렬 할 수 있습니다. 사전은 키-값 쌍 의 정렬되지 않은 모음입니다. 따라서 위의 대답은 사실이 아닌 위험한 가정을하는 것입니다.
Jack Lawrence

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

덕분에이 내게 도움이
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 사용에서 제거되었습니다.-self [self.startIndex.advancedBy (i)]
Romain

2
@TomSawyer 사전은 주문되지 않습니다.
Jose Ramirez

12

사전을 반복하고 for-in 및 enumerate를 사용하여 인덱스를 가져올 수 있습니다 (다른 사람들이 말했듯이 아래처럼 순서대로 나올 것이라는 보장은 없습니다)

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
}

정렬 된 사전을 만들려면 Generics를 살펴 봐야합니다.


1
456에 해당하는 인덱스를 검색하려면 어떻게해야합니까?
Famic Tech

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

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

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

@FamicTech, 크리스는 귀하의 질문에 대답
Suhaib

0

Java의 LinkedHashMap과 같은 것을 찾고있었습니다. 내가 착각하지 않았다면 Swift와 Objective-C는 하나도 없습니다.

내 초기 생각은 내 사전을 배열로 감싸는 것이 었습니다. [[String: UIImage]]하지만 사전에서 키를 잡는 것이 이상하다는 것을 깨달았 기 Array(dict)[index].key때문에 Tuples를 사용했습니다. 이제 내 배열 외모 좋아 [(String, UIImage)]내가하여 검색 할 수 있습니다 tuple.0. 더 이상 배열로 변환 할 필요가 없습니다. 내 2 센트.

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.