简体   繁体   English

如何在Swift中将[AnyObject]数组转换为[Hashable]或[AnyHashable]数组?

[英]How can I cast an array of [AnyObject] to an array of [Hashable] or [AnyHashable] in Swift?

I have an array of AnyObjects ( [AnyObject] ). 我有一个AnyObjects( [AnyObject] )数组。 I know most of these are Hashable . 我知道其中大多数都是可Hashable How would I "cast" this AnyObject to a Hashable/AnyHashable? 我如何将这个AnyObject“投射”到Hashable / AnyHashable? AnyHashable only takes a Hashable object as a parameter. AnyHashable仅将Hashable对象作为参数。

To cast one object to another you use as . 为了投一个对象到另一个你用as But the objects that can not be automatically converted (which is your case) you need to use either as? 但是不能自动转换的对象(在您的情况下)您需要将其as? or as! 还是as! . So the most simple way: 所以最简单的方法是:

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 

So one may crash while the other one will produce an optional array. 因此,一个可能崩溃,而另一个可能会生成一个可选数组。

Since you wrote "I know most of these are Hashable " I would say that none of these are OK. 自从您写了“我知道这些大多数都是可HashableHashable我会说这些都不是可以的。 You need to do the transform per-object and decide what to do with the rest. 您需要对每个对象进行转换,然后决定如何处理其余对象。 The most basic approach is: 最基本的方法是:

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)
}

So this method will convert your array and split it into two arrays. 因此,此方法将转换您的数组并将其拆分为两个数组。 You could then simply do let hashableArray: [AnyHashable] = separateHashable(inputArray: array).hashable . 然后,您可以简单地let hashableArray: [AnyHashable] = separateHashable(inputArray: array).hashable

But if you want to only extract those items that are hashable you can use convenience method on array compactMap 但是,如果您只想提取可compactMap项,则可以在数组compactMap上使用便捷方法

let hashableArray: [AnyHashable] = array.compactMap { $0 as? AnyHashable }

But in general this all very dangerous. 但是总的来说,这一切都很危险。 And also that is why you can't simply convert it to Hashable . 这就是为什么您不能简单地将其转换为Hashable The reason for it is that 2 items may both be hashable but are of different class. 原因是2个项目可能都是可散列的,但属于不同的类别。 And then both of the items may produce same hash even though they do not represent the same item. 然后这两个项目可能会产生相同的哈希,即使它们不代表相同的项目也是如此。 Imagine having 2 classes: 想象一下,有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 }
}

Now if I create an array like this: 现在,如果我创建一个像这样的数组:

let array: [AnyObject] = [
    Question(id: "1"),
    Answer(id: "1")
]

both of the items would produce the same hash and one would potentially overwrite the other. 这两个项目都会产生相同的哈希值,而其中一个可能会覆盖另一个。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM