我有一个AnyObjects([AnyObject]
)数组。我知道其中大多数是Hashable
。我如何将这个AnyObject“投射”到Hashable / AnyHashable?
AnyHashable仅将Hashable对象作为参数。
答案 0 :(得分:2)
要将一个对象投射到另一个对象,请使用as
。但是无法自动转换的对象(您的情况)需要使用as?
或as!
。所以最简单的方法是:
let hashableArray: [AnyHashable] = array as! [AnyHashable] // Will crash if even one object is not convertible to AnyHashable
let hashableArray: [AnyHashable]? = array as? [AnyHashable] // Will return nil if even one object is not convertible to AnyHashable
所以一个可能会崩溃,而另一个可能会生成一个可选数组。
自从您写了“我知道这些大多数都是Hashable
”以来,我会说这些都不是可以的。您需要对每个对象进行转换,然后决定如何处理其余对象。最基本的方法是:
func separateHashable(inputArray: [AnyObject]) -> (hashable: [AnyHashable], nonHashable: [AnyObject]) {
var hashableArray: [AnyHashable] = [AnyHashable]()
var nonHashableArray: [AnyObject] = [AnyObject]()
inputArray.forEach { item in
if let hashable = item as? AnyHashable {
hashableArray.append(item)
} else {
nonHashableArray.append(item)
}
}
return (hashableArray, nonHashableArray)
}
因此,此方法将转换您的数组并将其拆分为两个数组。然后,您可以简单地进行let hashableArray: [AnyHashable] = separateHashable(inputArray: array).hashable
。
但是,如果您只想提取可哈希的项,则可以在数组compactMap
上使用便捷方法
let hashableArray: [AnyHashable] = array.compactMap { $0 as? AnyHashable }
但是总的来说,这一切都是非常危险的。这也是为什么您不能简单地将其转换为Hashable
的原因。原因是2个项目可能都是可散列的,但属于不同的类别。然后这两个项目可能会产生相同的哈希,即使它们不代表相同的项目也是如此。想象一下,有2个班级:
struct Question: Hashable {
let id: String
var hashValue: Int { return id.hashValue }
}
struct Answer: Hashable {
let id: String
var hashValue: Int { return id.hashValue }
}
现在,如果我创建这样的数组:
let array: [AnyObject] = [
Question(id: "1"),
Answer(id: "1")
]
这两项都会产生相同的哈希值,而其中一项可能会覆盖另一项。