Swift:快捷方式展开选项数组

时间:2014-08-31 06:48:22

标签: swift

假设我们定义了一组选项:

var arrayOfOptionals: [String?] = ["Seems", "like", "an", nil, "of", "optionals"]

我可以强行打开它:var arrayForCrash = arrayOfOptionals.map { $0! }

但这会让app崩溃,还有其他任何简短的方法(没有明确展开)我如何解开一个可选数组?

7 个答案:

答案 0 :(得分:92)

此解决方案将为您提供一个新数组,其中包含所有值,并且所有值都已被过滤掉。

Swift 4.1:

let arrayOfOptionals: [String?] = ["Seems", "like", "an", nil, "of", "optionals"]
let arrayWithNoOptionals = arrayOfOptionals.compactMap { $0 }

Swift 2.0:

let arrayOfOptionals: [String?] = ["Seems", "like", "an", nil, "of", "optionals"]
let arrayWithNoOptionals = arrayOfOptionals.flatMap { $0 }

Swift 1.0:

let arrayOfOptionals: [String?] = ["Seems", "like", "an", nil, "of", "optionals"]
let arrayWithNoOptionals = arrayOfOptionals.filter { $0 != nil }.map { $0! }

答案 1 :(得分:9)

由于它是一个可选项数组,因此有些条目可能是nil。使用 nil coalescing运算符!转换为空字符串,而不是强制解包

nil

答案 2 :(得分:3)

虽然您可以使用flatMap { $0 }来删除nils,但是flatMap实际上是一个功能更强大的函数,并且有一个重载版本可以完成不同的操作(例如将[[Int]]展平为[Int]) 。如果你不小心,你可能会意外调用错误的功能。

我建议在SequenceType上使用扩展来删除nils。如果您使用removeNils(),您将能够基本上执行以下操作:

[1, nil, 2].removeNils() == [1, 2]

它的工作原理是使Optional符合OptionalType协议,该协议允许扩展包含SequenceType值的Optional

有关详细信息,请参阅original answer I posted

答案 3 :(得分:1)

我接受了@Cenny的回答,决定让操作员离开它:

prefix operator <!> {}

prefix func <!> <T>(array: [T?]) -> [T] {
  return array.filter{ $0 != nil }.map{ $0! }
}

我用它来解析JSON对象数组并过滤那些失败的对象:

static func parse(j: JSONArray) -> [Agency]? {
  return <!>j.map { self.parse($0) }
}

Swift 2+的更新:
使用flatMap运算符,它只返回非零对象

答案 4 :(得分:0)

怎么样:

import Foundation

var test: [String!] = ["this","is","a",nil,"test"]
for string in test {
    if string != nil {
        print(string)
    }
}

输出为thisisatest


如果我理解正确,请使用[String!]

答案 5 :(得分:0)

快捷键4

易于阅读和安全的方法来过滤任何序列的钉子

protocol OptionalProtocol {
    associatedtype Wrapped
    var optional: Wrapped? { get }
}

extension Optional: OptionalProtocol {
    var optional: Wrapped? {
        return self
    }
}

extension Sequence where Element: OptionalProtocol {
    var removingOptionals: [Element.Wrapped] {
        return self.compactMap { $0.optional }
    }
}

用法

let array: [Int?] = [1, 2, nil, 3, 4, nil]
print(array.removingOptionals) // prints [1, 2, 3, 4], has type [Int]

答案 6 :(得分:0)

更有趣的是,如何解开可选值的可选数组。在使用JSON时,进行处理非常重要,因为JSON可能包含某物数组的null值。

示例:

{ "list": null }
// or
{ "list": [null, "hello"] }

要填充Swift结构,我们可以有一个模型:

struct MyStruct: Codable {
    var list: [String?]?
}

为了避免将String??作为第一项工作,我们可以:

var myStruct = try! JSONDecoder.init().decode(MyStruct.self, from: json.data(using: .utf8)!)
let firstItem: String? = s1.list?.compactMap { $0 }.first

有了compactMap { $0 },我们可以避免

let i2: String?? = s1.list?.first

compactMap { $0 }等效于filter { $0 != nil }. map { $0! }