用 flatMap 展开

Unwrapping with flatMap

我想获取我知道存在的日期的工作日整数,如下所示:

let dayOfWeek =  Calendar.current.dateComponents([.weekday], from: row.date).weekday

但是,这个 returns 是可选的,我正在想办法避免强制展开它。

我的想法是:

let dayOfWeek = (row.date).compactMap( { Calendar.current.dateComponents([.weekday], from: [=11=]).weekday!
})

但是这给了我错误 "value of type 'Date' has no member 'compactMap'"

谁能告诉我哪里做错了,或者我应该如何解决这个问题?

在这种情况下无需避免强制解包。虽然 weekday 是可选的,但当您特别请求 .weekday 组件时,它永远不会是 nil

let dayOfWeek = Calendar.current.dateComponents([.weekday], from: row.date).weekday!

不需要选项。很简单:

let dayOfWeek = Calendar.current.component(.weekday, from: row.date)

请注意,flatMap 与此处无关,因为 row.date 不是可选的。但即使是,值得注意的是 Optional 方法 flatMap 的名称并未更改。还是flatMap。仅此名称的Sequence方法已更改为compactMap.

Swift Evolution 0187: Introduce Sequence.compactMap(_:)


所以,这仍然是 flatMap:

let foo: Int? = 42
let bar: String? = foo.flatMap { i -> String in
    return "The value is \(i)"
}
// Optional("The value is 42")

注意,返回值是可选的 String?。在您的示例中,您似乎正在尝试使用 flatMap 来解包您的可选内容,但这不是 flatMap 的用途。如果它可以打开 foo,它用于调用闭包,但如果它不能打开它,则返回 nil。所以它只是 returns 另一个可选的(在我上面的例子中是 String?)。

在Swift 4.1中重命名为compactMapflatMapSequence版本:

let baz = ["1", "2", "x", "3"]

let qux: [Int] = baz.compactMap { string -> Int? in
    return Int(string) // return integer value if it could convert it, return `nil` if not
}
// [1, 2, 3]

为了让它更加混乱,还有 flatMap 与序列一起使用:

let letters = ["a", "b", "c"]

let quux = letters.map { Array(repeating: [=13=], count: 3) }
// [["a", "a", "a"], ["b", "b", "b"], ["c", "c", "c"]]

let quuz = letters.flatMap { Array(repeating: [=13=], count: 3) }
// ["a", "a", "a", "b", "b", "b", "c", "c", "c"]