使用Any / AnyObject的嵌套数组

时间:2016-05-03 13:39:32

标签: arrays swift

根据Apple的官方书籍#34; Swift编程语言(Swift 2.1)":

  
      
  • AnyObject可以表示任何类类型的实例。
  •   
  • 任何可以表示任何类型的实例,包括函数类型。
  •   

知道这一点,我想使用Any数组模拟类似Python的嵌套列表。

let array = [1, 2, [3, 4], [5, 6, [7, 8]], 1]

由于IntArray是值类型,我认为array将被键入为[Any]

但这并非如此:

func flatten(list:[Any]) -> [Any] {
    var new = [Any]()
    for element in list {
        if let array = element as? [Any] {
            // this code never runs
            let flattened = flatten(array)
            for x in flattened {
                new.append(y)
            }
        }else{
            new.append(element)
        }
    }
    return new
}

注意:首先调用此函数会给我EXC_BAD_INSTRUCTION错误,直到我做了这个调整:

let array : [Any] = [1, 2, [3, 4], [5, 6, [7, 8]], 1]

Output :   [1, 2, [3, 4], [5, 6, [7, 8]], 1]
Expected : [1, 2, 3, 4, 5, 6, 7, 8, 1]

原因不明的解决方案:

我通过Any

替换了此示例AnyObject中的所有位置

现在的数字类型为NSNumber

func flatten(list:[AnyObject]) -> [AnyObject] {
    var new = [AnyObject]()
    for element in list {
        if let array = element as? [AnyObject] {
            let flattened = flatten(array)
            for x in flattened {
                new.append(y)
            }
        }else{
            new.append(element)
        }
    }
    return new
}

Output :   [1, 2, 3, 4, 5, 6, 7, 8, 1]
Expected : [1, 2, 3, 4, 5, 6, 7, 8, 1]

问题:

为什么它与[AnyObject] / NSArray合作而不与[Any]一起使用,尽管整数文字主要是Int类型而不是NSNumber和数组文字的类型为Array而不是NSArray我的例子有问题吗?

1 个答案:

答案 0 :(得分:0)

当你使用Any时,Swift会将你的嵌套数组元素包装到NSArray中而不包含在Swift数组中(它不能包含所有Objective-C类型)。因此,如果您使用if let array = element as? [Any] {,则您的测试Any将不会成立,因为生成的数组不是[Any]类型而是NSArray

因此,如果您想要一个管理Any的功能,您可以更改您的测试:

if let nestedArray = element as? NSArray {

然后,您必须使用NSArray原型定义新的flattenArray()函数:

func flattenArray(array: NSArray) -> [Any] {

    var flattenedArray: [Any] = []

    for element in array {

        // We have an array
        if let nestedArray = element as? NSArray {
            flattenedArray = flattenedArray + flattenArray(nestedArray)
        } else {
            // We have a single element
            flattenedArray.append(element)
        }
    }

    return flattenedArray
}

func flattenArray(array: [Any]) -> [Any] {

    var flattenedArray: [Any] = []

    for element in array {

        // We have an array
        if let nestedArray = element as? NSArray {
            flattenedArray = flattenedArray + flattenArray(nestedArray)
        } else {
            // We have a single element
            flattenedArray.append(element)
        }
    }

    return flattenedArray
}

它会起作用。

我们可以想象一个更优雅的解决方案,但是通过这个例子,您可以了解这个问题背后的想法。