You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

为什么compactMap无法移除Mirror生成的[Any?]数组中的nil值?

问题根源

Mirror.Child.value的返回类型是Any,你将其映射为[Any?]时,相当于给所有元素额外包了一层Optional。如果元素本身就是Optional类型(比如你的代码里的optionalString、optionalInt),就会形成两层嵌套的Optional(即Any??)。

compactMap默认只会解开最外层的Optional,此时最外层Optional永远有值(哪怕内部包装的是.none),所以不会触发过滤逻辑,nil也就保留了下来。

你后面两个测试用例能正常生效,是因为直接构造的[Any?]只有一层Optional,compactMap可以正常识别并过滤nil。


解决方案

写一个递归解包任意嵌套Optional的辅助方法,再配合compactMap使用即可:

// 递归解开任意层级的Optional包装,为nil则返回nil
func unwrap(any: Any) -> Any? {
    let mirror = Mirror(reflecting: any)
    // 非Optional类型直接返回原值
    guard mirror.displayStyle == .optional else { return any }
    // Optional为空的情况返回nil
    guard let firstChild = mirror.children.first else { return nil }
    // 递归解开内层可能存在的嵌套Optional
    return unwrap(any: firstChild.value)
}

// 原逻辑修改为
let compactArrayOfChildrenValues: [Any] = arrayOfChildrenValues.compactMap { unwrap(any: $0) }

修改后打印结果就是你预期的["a", "b", "c"]。


内容的提问来源于stack exchange,提问作者swiftPunk

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.09.24 14:45:03