struct Data {
let storage: [String: Int]
init(_ pairs: KeyValuePairs<String, Int>) {
storage = Dictionary(uniqueKeysWithValues: pairs)
}
}
编译错误:
Initializer'init(uniqueKeysWithValues:('需要类型'KeyValuePairs<字符串,Int>。元素'(又名'(键:String,值:Int('(和"(String,Int("是等效的
还有什么比用KeyValuePairs初始化Dictionary(uniqueKeysWithValues:(更自然的呢!?这太荒谬了,不可能直截了当地做requires '(key: String, value: Int)' and '(String, Int)' be equivalent
它们是等效的!
type(of: (key: "", value: 0)) == type(of: ("", 0)) // false
您需要另一个过载,或者只需要就地删除标签。
public 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.
@inlinable init<Elements: Sequence>(uniqueKeysWithValues keysAndValues: Elements)
where Elements.Element == Element {
self.init(
uniqueKeysWithValues: keysAndValues.map { ($0, $1) }
)
}
}
XCTAssertEqual(
Dictionary(
uniqueKeysWithValues: ["🍐": "🪂", "👯♀️": "👯♂️"] as KeyValuePairs
),
.init(
uniqueKeysWithValues: [("🍐", "🪂"), ("👯♀️", "👯♂️")]
)
)
由于Swift不支持Splatting(目前(,以下是实现它的方法:
struct Data {
let storage: [String: Int]
init(_ pairs: KeyValuePairs<String, Int>) {
storage = Dictionary(uniqueKeysWithValues: pairs.reduce(into: [String: Int]()) { $0[$1.0] = $1.1 } .map { $0 })
}
}
用法:
let data = Data(KeyValuePairs(dictionaryLiteral: ("a", 1), ("b", 2)))
您也可以使用reduce
:
storage = pairs.reduce(into: [String: Int]()) { $0[$1.key] = $1.value }
即使您在pairs
中有重复的密钥,这也会起作用(目前它从重复项中获取最后一项:
let data = Data(["a": 1, "b": 2, "a": 3] as KeyValuePairs)
print(data.storage)
// ["a": 3, "b": 2]
如果你需要它来拿走你可以做的第一件事:
storage = pairs.reduce(into: [String: Int]()) { $0[$1.key] = $0[$1.key] ?? $1.value }
(或更短(
storage = pairs.reduce(into: [String: Int]()) { $0[$1.0] = $0[$1.0] ?? $1.1 }
此打印:
let data = Data(["a": 1, "b": 2, "a": 3] as KeyValuePairs)
print(data.storage)
// ["a": 1, "b": 2]
•修复:
storage = Dictionary(uniqueKeysWithValues: Array(pairs))
•原因:
您尝试使用的方法是:
public init<S>(uniqueKeysWithValues keysAndValues: S) where S : Sequence, S.Element == (Key, Value)
它缺少S.Element == (Key, Value)
合规性。
•更进一步:
请注意,如果您有重复的密钥,则会出现错误。你可以使用:
storage = Dictionary(Array(paris)) { _, new in
return new //if you want to keep the last "key" value, or the reverse
}
•其他可能性:
在[String:String]中转换[(key:String,value:String(]