如何从Swift中的Dictionary获取特定索引处的密钥?


113

Dictionary在Swift中有一个,我想在特定索引处获取一个键。

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

我知道我可以遍历密钥并记录它们

for key in myDict.keys{

    NSLog("key = \(key)")

}

但是,奇怪的是,这样的事情是不可能的

var key : String = myDict.keys[0]

为什么呢


10
请注意,Swift字典不保证采用任何特定顺序。所以你不能肯定想到的是,按键的顺序进行索引你把他们英寸
RADEX

+1 @radex,并且如果可能的话,还想添加一个阅读您的陈述的信息来源,我们将不胜感激。
2014年

Answers:


189

这是因为keysreturn 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因为它不会复制keys数组,并且不应该复制字典的内部结构,尽管可能这样做。
大卫·贝里

5
请记住,不能保证会返回哪个键,但是要注意返回的“视图”类型。删除了我的答案,因为它实际上不适用于该问题。
罗布·纳皮尔2014年

8
为了澄清Rob的意思,虽然看起来每次按键总是按相同的顺序排列,但事实并非如此,而只是实现细节。您很有可能可以添加键“ foo”,并且内部表示形式将完全重新排序字典。字典是键值对的无序集合。因此,以上答案做出了不成立的危险假设。
杰克·劳伦斯

8
如果您需要按特定顺序排列键,请保留它们的数组。然后,您可以像使用它们myDict[keysArray[0]]
Zev Eisenberg 2014年

1
不起作用...'NSDictionary' is not convertible to '_ArrayBuffer<T>'
克里斯

53

斯威夫特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]]然后可以通过索引进行访问。
彼得R

29

这是一个小扩展,用于按索引访问字典中的键和值:

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

3
在Swift 2.0使用中已删除了“高级” API-self [self.startIndex.advancedBy(i)]
Romain

2
@TomSawyer字典未排序。
Jose Ramirez

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 '18

2
@Max,这是旧的Swift语法。现在您可以使用: dict.enumerated().forEach { (index, element) in ... }
Matthew Korporaal


5

SWIFT3。第一个元素的示例

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

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

3
如果我想获取关键是波兰语的索引怎么办?
Famic Tech '18

5

Swift 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 '18

1
arrayIndex = 0,ageDictIndex = 1,Array(array_has_dictionary [arrayIndex] .keys)[ageDictIndex] = xxxx
克里斯蒂安

@FamicTech,克里斯(Kris)回答了您的问题
Suhaib '18

0

我一直在寻找Java中的LinkedHashMap之类的东西。如果我没记错的话,Swift和Objective-C都没有。

我最初的想法是将字典包装在数组中。[[String: UIImage]]但是后来我意识到从字典中获取密钥很古怪,Array(dict)[index].key所以我选择了Tuples。现在我的数组看起来像[(String, UIImage)]这样,所以我可以通过检索它tuple.0。不再将其转换为数组。只是我的2美分。

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.