如何将可选整数数组连接到字符串?

时间:2017-01-05 15:57:11

标签: arrays swift functional-programming optional

给定[Int?],需要从中构建字符串。

此代码段有效

    let optionalInt1: Int? = 1
    let optionalInt2: Int? = nil

    let unwrappedStrings = [optionalInt1, optionalInt2].flatMap({ $0 }).map({ String($0) })
    let string = unwrappedStrings.joined(separator: ",")

但我不喜欢flatMap后跟map。有没有更好的解决方案?

7 个答案:

答案 0 :(得分:3)

这是另一种方法:

[optionalInt1, optionalInt2].flatMap { $0 == nil ? nil : String($0!) }

答案 1 :(得分:3)

您可以在应用于数组的flatMap闭包内使用map method of Optional,利用前者将返回nil而不进入提供的闭包的事实,以防可选的本身是nil

let unwrappedStrings = [optionalInt1, optionalInt2]
    .flatMap { $0.map(String.init) }

另外,如果你不在(或flatMapmap)包裹尾随闭包,并进一步利用初始化引用String.init将会(在这种情况下)非暧昧地解析为正确的String初始值设定项(如上所述),链式flatMapmap无需查看"膨胀" ,这也是一个完全有效的方法(链式flatMapmap也保持语义的价值)。

let unwrappedStrings = [optionalInt1, optionalInt2]
    .flatMap{ $0 }.map(String.init) 

答案 2 :(得分:2)

如果您不喜欢flatMapmap,可以替换此

[optionalInt1, optionalInt2].flatMap({ $0 }).map({ String($0) })

用这个

[optionalInt1, optionalInt2].flatMap { $0?.description }

总结

let optionalInt1: Int? = 1
let optionalInt2: Int? = nil

let result = [optionalInt1, optionalInt2]
    .flatMap { $0?.description }
    .joined(separator: ",")

更新

自:

  • as @Hamish 指出Swift团队不鼓励直接访问description
  • 由于双循环,OP希望避免flatMap + map连接

我提出了另一种解决方案

let result = [optionalInt1, optionalInt2].flatMap {
        guard let num = $0 else { return nil }
        return String(num)
    }.joined(separator: ",")

答案 3 :(得分:2)

其他答案使用flatMap来消除nil元素,并需要调用joined()来组合元素并添加逗号。

使用joined()添加逗号当然是第二次通过 阵列。这是一种使用reduce一次完成此操作的方法:

let arr: [Int?] = [nil, nil, 1, 2, 3, nil, 4, nil, 5, nil]

let result = arr.reduce("") { $1 == nil ? $0 : $0.isEmpty ? "\($1!)" : $0 + ",\($1!)" }

print(result)

输出:

1,2,3,4,5

<强>解释

此示例使用reduce按元素构造结果字符串元素。

reduce是一个在序列上调用的方法。它采用初始值(在此示例中为"")和一个闭包,它将序列中的下一个元素与部分结果组合在一起以创建下一个部分结果。

对序列中的每个元素(即数组arr)调用闭包。闭包首先检查元素是否为nil,如果是,则返回未修改的部分结果。如果元素不是nil,则它检查部分结果是否仍为空字符串。如果它为空,则这是结果中的第一个元素,因此它返回仅由元素组成的字符串。如果部分结果不为空,则会将以,开头的新元素添加到部分结果中。

答案 4 :(得分:1)

<强> Swift3.1

[1,2,3] .flatMap({String(describe:$ 0)})。joined(separator:“”)

//“1 2 3”(没有引号确定)

答案 5 :(得分:0)

完全避免使用flatMap和地图。然而,创建一个本地变种。

let optionalInt1: Int? = 1
let optionalInt2: Int? = nil
let optionalInts = [optionalInt1, optionalInt2]

var strings = [String]()
for optInt in optionalInts {
    if let integer = optInt {
        strings.append(String(integer))
    }
}
let string = strings.joined(separator: ",")

答案 6 :(得分:0)

由于def save(self, *args, **kwargs): self.clean() super().save(*args, **kwargs) 符合Int,因此您可以使用可选链接和CustomStringConvertible属性:

description