FlatMap使用Int类型数组给出警告,但不使用String类型数组给出警告

Mun*_*han 4 ios flatmap swift

当我flatMapString类型数组一起使用时,它没有给出任何警告,而在Int类型数组的情况下它给出了警告。为什么?例:

let strings = [
    "I'm excited about #SwiftUI",
    "#Combine looks cool too",
    "This year's #WWDC was amazing"
]
strings.flatMap{$0 + "."} //No warning

let ints = [
   2,3,4
]
ints.flatMap{$0 + 1} //'flatMap' is deprecated: Please use compactMap(_:) for the case where closure returns an optional value
Run Code Online (Sandbox Code Playgroud)

Rob*_*Rob 8

这是因为这是两种不同的flatMap方法。

因此,在回答您的问题之前,让我们退后一步,考虑一下flatMap现在打算做什么,即将变换应用于序列并连接所得到的序列。典型示例用于“展平”数组):

let arrayOfArrays = [[1, 2], [3, 4, 5]]
let array = arrayOfArrays.flatMap { $0 }
print(array)
Run Code Online (Sandbox Code Playgroud)

导致:

[1、2、3、4、5]

flatMap数组数组展平为单个数组。

令人困惑的是,现在有一个不推荐使用的方法flatMap将执行转换,将可选结果包装在序列或集合中,但删除那些是nil。幸运的是,现在已将其重命名compactMap以避免混淆。因此,这就是您收到警告的原因。

考虑:

let input: [Int?] = [0, 1, nil, 3]
let results = input.flatMap { $0 } // 'flatMap' is deprecated: Please use compactMap(_:) for the case where closure returns an optional value
print(results)
Run Code Online (Sandbox Code Playgroud)

导致:

[0,1,3]

所以,我们应该取代flatMapcompactMap作为建议:

let input: [Int?] = [0, 1, nil, 3]
let results = input.compactMap { $0 }
print(results)
Run Code Online (Sandbox Code Playgroud)

这将给我们带来预期的结果,而不会发出警告。


因此,让我们回到您的示例。因为字符串是字符数组,所以它会让您如履薄冰:

let strings = [
    "I'm excited about #SwiftUI",
    "#Combine looks cool too",
    "This year's #WWDC was amazing"
]
let stringResults = strings.flatMap { $0 + "." }
print(stringResults)
Run Code Online (Sandbox Code Playgroud)

结果是扁平化的字符数组:

[“ I”,“ \'”,“ m”,“”,“ e”,“ x”,“ c”,“ i”,“ t”,“ e”,“ d”,“”,“ a “,” b“,” o“,” u“,” t“,”“,”#“,” S“,” w“,” i“,” f“,” t“,” U“,” I”,“。”,“#”,“ C”,“ o”,“ m”,“ b”,“ i”,“ n”,“ e”,“”,“ l”,“ o”, “ o”,“ k”,“ s”,“”,“ c”,“ o”,“ o”,“ l”,“”,“ t”,“ o”,“ o”,“。”, “ T”,“ h”,“ i”,“ s”,“”,“ y”,“ e”,“ a”,“ r”,“ \'”,“ s”,“”,“#”,“ W”,“ W”,“ D”,“ C”,“”,“ w” ,“ a”,“ s”,“”,“ a”,“ m”,“ a”,“ z”,“ i”,“ n”,“ g”,“。”]

那显然不是您想要的,但是编译器让您如愿以偿,您想将字符数组(即字符串数组)展平为平坦的字符数组。这就是为什么没有警告的原因。


不用说,在您的示例中,您既不会使用flatMap(因为您不处理数组数组),也不会使用compactMap(因为您不处理可选对象)。您只需要使用map

let strings = [
    "I'm excited about #SwiftUI",
    "#Combine looks cool too",
    "This year's #WWDC was amazing"
]
let stringsResults = strings.map { $0 + "." }
print(stringsResults)

let ints = [2, 3, 4]
let intsResults = ints.map { $0 + 1 }
print(intsResults)
Run Code Online (Sandbox Code Playgroud)

完全不相关,但是出于充分披露的目的(但有使它变得更加混乱的风险),实际上还有另一种 flatMap方法(!),即一种Optional类型。诚然,这可以说比数组展平(即序列级联)再现使用得少,但是我应该承认它的存在。

flatMap对方法Optional“评估给出闭合时,该Optional实例不是nil,传递展开的值作为参数。”但如果是可选的nil,这flatMap将返回nil了。

例如:

func message(for value: Int?) -> String? {
    return value.flatMap { "The value is \($0)" }
}
Run Code Online (Sandbox Code Playgroud)

因此,如果value为was 42,则结果为可选字符串"The value is 42"。但是如果valuenil,那么结果将是nil

的表达flatMap与当前的问题无关,但是为了完整起见,我想提及它。