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

时间:2016-06-30 10:35:38

标签: swift slice

我正在尝试将myDictionary.dropFirst()转换为缺少一个键的新词典(我不关心哪一个)。 dropFirst()返回一个Slice。我想要一个与myDictionary相同类型的新词典。

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

非常感谢提前。

2 个答案:

答案 0 :(得分:5)

DictionarySlice没有像ArraySlice这样的东西。相反,dropFirst()会返回一个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]

我不建议这样做,因为

  • 您不知道哪个键值对将被删除,
  • 它也不是真正随机的。

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

答案 1 :(得分:0)

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 { ($0.key, $0.value) }
    )
  }
}