可以将swift选项映射到新值吗?

时间:2016-04-03 19:55:12

标签: swift

在java 8中,您可以执行以下操作: -

Optional<String> foo = Optional.empty(); // or Optional.of("hello");
foo.map(String::toUpperCase).orElse("Empty String")

编辑 - 另一个例子

class Bar {
  public Bar(final String baz) { ... }
}

foo.map(f -> new Bar(f)) // has mapped into an optional Bar

那个toUpperCase有点过于简单;我更多的想法是能够指定一个lambda或函数,它可以根据一个可选的present提供一个变异的值。

我看到你可以在swift中执行以下操作: -

guard let foo = optional else { return "Empty String" }

这是非常有用的,也是

optional ?? "Empty String"

但是有没有办法根据可选的值来映射值?即如果存在某个值,您可以返回一个变异值吗?

此功能也适用于java / c#collections

2 个答案:

答案 0 :(得分:3)

对于给定的可选字符串数组,您可以在map操作中使用可选链接

let foo: [String?] = ["foo", "bar", nil, "baz"]

let bar = foo.map { $0?.uppercaseString ?? "Empty string" }
print(bar) // ["FOO", "BAR", "Empty string", "BAZ"]

一个可能更有用的替代方法是应用flatMap操作来简单地从字符串数组中删除nil - 值可选条目

let foo: [String?] = ["foo", "bar", nil, "baz"]

let bar = foo.flatMap { $0?.uppercaseString }
print(bar) // ["FOO", "BAR", "BAZ"]

W.r.t。你的评论,你可以,例如在Foo操作中为某个结构flatMap调用一个可用的初始化程序,在初始化程序成功的情况下产生一个Foo个实例数组。

struct Foo {
    let foo: String
    init?(bar: String?) {
        guard let foo = bar else {
            return nil
        }
        self.foo = foo
    }
}

let foo: [String?] = ["foo", "bar", nil, "baz"]
let bar = foo.flatMap { Foo(bar: $0) }
print(bar) // [Foo(foo: "foo"), Foo(foo: "bar"), Foo(foo: "baz")]

答案 1 :(得分:1)

在你的例子中,那只是:

optional?.uppercaseString ?? "EMPTY STRING"

或者如果您希望在违约后修改:

(optional ?? "empty string").uppercaseString

你有没有更复杂的想法?

(您可能不熟悉?.运算符。它在Swift中称为可选链接,类似于map。)