代码之家  ›  专栏  ›  技术社区  ›  swiftPunk Alexander

为什么compactMap不能从可选Any的数组中删除nil值?

  •  -1
  • swiftPunk Alexander  · 技术社区  · 4 年前

    我有这个简单的代码,我想做的是删除 nil 值来自 [Any?] 并制作 [Any] 。但是compactMap不起作用!

    let optionalString: String? = nil
    let optionalInt: Int? = nil
    
    let customTuple = (optionalString, "a", "b", "c", optionalInt)
    
    let arrayOfChildren: [Mirror.Child] = Array(Mirror(reflecting: customTuple).children)
    
    let arrayOfChildrenValues: Array<Any?> = arrayOfChildren.map({ element in element.value })
    
    let compactArrayOfChildrenValues: Array<Any> = arrayOfChildrenValues.compactMap({ element in element })
    
    print(compactArrayOfChildrenValues)
    

    打印结果:

    [nil,“a”,“b”,“c”,nil]


    测验

    例如,下面的简单测试就可以了!但我在顶部的代码没有!我在这里缺少什么?

    let optionalString: String? = nil
    let optionalInt: Int? = nil
    let array: [Any?] = [optionalString, "Hello, world!", optionalInt, 1000]
    print(array.compactMap({ element in element }))
    

    后果

    [“你好,世界!”,1000]


    另一项测试:

    let optionalString: String? = nil
    let optionalInt: Int? = nil
    
    let arrayOfChildrenValues: Array<Any?> = [optionalString, "a", "b", "c", optionalInt]
    let compactArrayOfChildrenValues: Array<Any> = arrayOfChildrenValues.compactMap({ element in element })
    
    print(compactArrayOfChildrenValues)
    

    后果

    [“a”、“b”、“c”]

    1 回复  |  直到 4 年前
        1
  •  1
  •   George    4 年前

    首先,更改的类型 arrayOfChildrenValues [Any] ,因此它不再是可选的,因为 \.value 不返回可选项。

    现在-您想看看类型的元素 Any 是可选的。为此,您可以尝试将其与匹配 Optional<Any>.none .

    更换以下部件:

    let arrayOfChildrenValues: [Any] = arrayOfChildren.map(\.value)
    
    let compactArrayOfChildrenValues: [Any] = arrayOfChildrenValues.filter { element in
        switch element {
        case Optional<Any>.none: return false
        default: return true
        }
    }
    

    其他方式

    这是另一种方式:

    let arrayOfChildrenValues: [Any] = arrayOfChildren.map(\.value)
    
    let compactArrayOfChildrenValues: [Any] = (arrayOfChildrenValues as [Any?]).compactMap { $0 }
    

    然而,还有另一种方法会发生一些奇怪的行为,我不确定我是否能完全理解。

    这是代码:

    let arrayOfChildrenValues: [Any?] = arrayOfChildren.map(\.value)
    
    let compactArrayOfChildrenValues: [Any] = arrayOfChildrenValues.compactMap { $0 }
    

    这之所以奇怪,是因为所有其他方法都能与 子值数组 被表达为 { element in element.value } ,然而 只有 在使用关键路径时有效。也许是因为返回类型被推断为 [Any?] ,所以它执行与上面的示例类似的铸造?

    为什么你的另一个例子有效?

    原因 compactMap 不起作用 任何 是因为类型的值 任何 不能是 nil ,因为它不是可选的。

    你可以通过尝试来测试这一点 compactMap 在…上 任何 而不是 任何 。修改您的另一个示例,如下所示:

    let anyArray: [Any] = array.map { $0 as Any }
    print(anyArray.compactMap({ element in element }))
    

    注意这张照片 [nil, Optional("Hello, world!"), nil] -并且还将我们所有的值封装在一个可选值中,因为实际上这仍然是类型 任何 ,“伪装”为 任何 .