如何在 Swift 中将字典切片转换为字典

How to a convert a Dictionary Slice to a Dictionary in Swift

我正在尝试将 myDictionary.dropFirst() 转换为缺少一个键的新字典(我不在乎是哪个键)。 dropFirst() returns 一个切片。我想要一个与 myDictionary.

类型相同的新词典

您可以像这样将数组切片转换为数组 let array = Array(slice)。字典的等价物是什么?如果我尝试 Dictionary(slice) 我会得到编译错误 Argument labels '(_:)' do not match any available overloads

非常感谢。

没有 DictionarySliceArraySlice 这样的东西。相反,dropFirst() returns a Slice<Dictionary> 不像 Dictionary 那样支持键下标。但是,您可以使用键值对遍历 Slice<Dictionary>,就像使用 Dictionary:

一样
let dictionary = ["a": 1, "b": 2, "c": 3]

var smallerDictionary: [String: Int] = [:]

for (key, value) in dictionary.dropFirst() {
    smallerDictionary[key] = value
}

print(smallerDictionary) // ["a": 1, "c": 3]

扩展会让这更优雅:

extension Dictionary {

    init(_ slice: Slice<Dictionary>) {
        self = [:]

        for (key, value) in slice {
            self[key] = value
        }
    }

}

let dictionary = ["a": 1, "b": 2, "c": 3]
let smallerDictionary = Dictionary(dictionary.dropFirst())
print(smallerDictionary) // ["a": 1, "c": 3]

不过我真的不建议这样做,因为

  • 你不知道哪个键值对会被丢弃,并且
  • 它也不是真正随机的。

但如果你真的想这样做,现在你知道怎么做了。

Dictionary(uniqueKeysWithValues: [1: 1, 2: 2, 3: 3].dropFirst())

请参阅我的 Note 以了解为什么需要此重载才能进行编译。

extension Dictionary {
  /// Creates a new dictionary from the key-value pairs in the given sequence.
  ///
  /// - Parameter keysAndValues: A sequence of key-value pairs to use for
  ///   the new dictionary. Every key in `keysAndValues` must be unique.
  /// - Returns: A new dictionary initialized with the elements of `keysAndValues`.
  /// - Precondition: The sequence must not have duplicate keys.
  /// - Note: Differs from the initializer in the standard library, which doesn't allow labeled tuple elements.
  ///     This can't support *all* labels, but it does support `(key:value:)` specifically,
  ///     which `Dictionary` and `KeyValuePairs` use for their elements.
  init<Elements: Sequence>(uniqueKeysWithValues keysAndValues: Elements)
  where Elements.Element == Element {
    self.init(
      uniqueKeysWithValues: keysAndValues.map { ([=11=].key, [=11=].value) }
    )
  }
}