Search code examples
iosswiftmappingnsarrayswift4

Mapping from array of dictionaries to array of numbers in Swift


Here is a function that should turn an an array of key-value pairs for orders NSArray containing Dictionary<String, Any> to an array of IDs for each order ([NSNumber]).

However, I am still having problem with the type conversion, the error:

Type 'Any' has no subscript members

How to perform the mapping cleanly in Swift?

@objc static func ordersLoaded(notification:Notification) -> [NSNumber] {   

    // Function receives a Notification object from Objective C     
    let userInfo:Dictionary = notification.userInfo as! Dictionary<String, Any>

    // orders is an array of key-value pairs for each order Dictionary<String,Any>
    let ordersWithKeyValuePairs:NSArray = userInfo["orders"] as! NSArray // Here a typed array of Dictionaries would be preferred

    // it needs to be simplified to an array of IDs for each order (NSNumber)
    // orderID is one of the keys
    let orderIDs:[NSNumber];
    orderIDs = ordersWithKeyValuePairs.flatMap({$0["orderID"] as? NSNumber}) // Line with the error
    /*
    orderIDs = ordersWithKeyValuePairs.map({
        (key,value) in
        if key==["orderID"] {
            return value
        } else {
            return nil
        }
    }) as! [NSNumber]
    */

    return orderIDs
}

Solution

  • Here is what worked, casting ordersWithKeyValuePairs to [Dictionary<String, Any>] solved the problem to me:

    @objc static func ordersLoaded(notification:Notification) -> [NSNumber] {   
    
        // Function receives a Notification object from Objective C     
        let userInfo:Dictionary = notification.userInfo as! Dictionary<String, Any>
    
        // orders is an array of key-value pairs for each order Dictionary<String,Any>
        let ordersWithKeyValuePairs:[Dictionary<String, Any>] = userInfo["orders"] as! [Dictionary<String, Any>]
        // it needs to be simplified to an array of IDs for each order (NSNumber)
        // orderID is one of the keys
        let orderIDs:[NSNumber];
        orderIDs = ordersWithKeyValuePairs.flatMap({$0["orderID"] as? NSNumber}) // Line with the error
    
        return orderIDs
    }