在组合两个可选的数组时遇到一些麻烦。不是包含可选项的数组。
let a : [String]? = ["foo"]
let b : [String]? = nil
或
let a : [String]? = nil
let b : [String]? = nil
或
let a : [String]? = ["foo"]
let b : [String]? = ["bar"]
这显然不起作用,因为数组是可选的
let combinedArrays : [String]? = a + b
使用功能性或其他更清晰的方法组合数组a和b,是否有比传统if let
方法更简洁的方法?
更新 上面的例子是设计的,但下面是我试图做的更真实的例子:
func pinToAllSidesOfSuperView() -> [NSLayoutConstraint]?
{
let horizontalConstraints : [NSLayoutConstraint]? = pinViewToLefAndRight()
let verticalConstraints : [NSLayoutConstraint]? = pinViewToTopAndBottom()
return horizontalConstraints + verticalConstraints
}
返回一个可选的返回值vs一个空数组会很好,所以该方法的调用者仍然可以使用可选功能(即if let
,guard
等)与简单检查if { {1}}。
答案 0 :(得分:8)
我不确定这是否足够整洁,但无论如何它会给出组合的字符串数组
var combined = (a ?? []) + (b ?? [])
许多其他选项之一是使其成为计算属性,如果组合数组为空,则返回nil
var combined:[String]?{
let c = (a ?? []) + (b ?? [])
return c.isEmpty ? nil : c
}
答案 1 :(得分:6)
我会这样做:
func +<T>(lhs: Array<T>?, rhs: Array<T>?) -> Array<T>? {
switch (lhs, rhs) {
case (nil, nil):
return nil
case (nil, _):
return rhs
case (_, nil):
return lhs
default:
return lhs! + rhs!
}
}
let foo: [Int]? = nil
let bar: [Int]? = [1]
foo + foo // -> nil
foo + bar // -> [1]
bar + foo // -> [1]
bar + bar // -> [1, 1]
答案 2 :(得分:4)
而不是nil只是让它们成为空数组?
答案 3 :(得分:1)
采取以下解决方案之一:
1)有点难看
let a : [String]? = ["foo"]
let b : [String]? = ["bar"]
let c = (a != nil ? a! : []) + (b != nil ? b! : []) // ["foo", "bar"]
2)重新加载[String]?
func +(a: [String]?, b: [String]?) -> [String] {
var s1 = a != nil ? a! : []
let s2 = b != nil ? b! : []
for n in s2 {
s1.append(n)
}
return s1
}
let a : [String]? = ["foo"]
let b : [String]? = ["bar"]
let c : [String]? = nil
let result1 = a + b // ["foo", "bar"]
let result2 = a + c // ["foo"]
顺便说一句!在覆盖运算符中,您无法编写类似:
的内容func +(a: [String]?, b: [String]?) -> [String] {
return (a != nil ? a! : []) + (b != nil ? b! : [])
}
如您所见,它将导致无限递归,因此我使用了循环和append()
答案 4 :(得分:1)
对于更实用的方法,您可以为此使用compactMap
和flatMap
。
类似以下内容:
let a : [String]? = ["foo"]
let b : [String]? = ["bar"]
let combined = [a, b] // create array with both optional arrays
.compactMap({ $0 }) // remove optional from it
.flatMap({ $0 }) // merge elements into a final array
希望有帮助!
答案 5 :(得分:0)
Ben的answer是正确的,也可以应用于更复杂的情况:
let arr1: [CGFloat?] = [3, 2, nil]
let arr2: [CGFloat?]? = [4, 5, nil]
let allValues: [CGFloat] = [
arr1.compactMap({ $0 }),
arr2?.compactMap ({ $0 })
]
.compactMap({ $0 })
.flatMap({ $0 })
print(allValues) // [3.0, 2.0, 4.0, 5.0]