如果在Swift中创建了两个数组,就像这样:
var a:[CGFloat] = [1, 2, 3]
var b:[CGFloat] = [4, 5, 6]
它们如何合并为[1, 2, 3, 4, 5, 6]
?
+
来连接数组,并构建一个新数组。let c = a + b
print(c) // [1.0, 2.0, 3.0, 4.0, 5.0, 6.0]
或者使用+=
(或append
)将一个数组附加到另一个数组:
a += b
// Or:
a.append(contentsOf: b) // Swift 3
a.appendContentsOf(b) // Swift 2
a.extend(b) // Swift 1.2
print(a) // [1.0, 2.0, 3.0, 4.0, 5.0, 6.0]
AnyObject
表示一个对象,这意味着它是从一个类类型实例化出来的东西。CGFloat
不是一个对象,而是一个标量值。数组可以包含标量,除非它们被定义为包含 AnyObject
或进一步细化。然而,我怀疑问题在于数组被包装成可选项,因此您必须首先使用 !
或 ?
对其进行解包。 - Owen Godfreya
的b
部分是否被修改(因此在a.appendContentsOf(b)
期间可能省略b
的副本)? - Ephemera使用 Swift 5,根据您的需要,您可以选择以下六种方式之一来合并两个数组。
Array
的 +(_:_:)
泛型运算符将两个数组合并成一个新数组Array
有一个 +(_:_:)
泛型运算符,+(_:_:)
的声明如下:
通过连接集合和序列的元素创建新的集合。
static func + <Other>(lhs: Array<Element>, rhs: Other) -> Array<Element> where Other : Sequence, Self.Element == Other.Element
以下是 Playground 的示例代码,展示了如何使用 +(_:_:)
通用运算符将两个 [Int]
类型的数组合并成一个新数组:
let array1 = [1, 2, 3]
let array2 = [4, 5, 6]
let flattenArray = array1 + array2
print(flattenArray) // prints [1, 2, 3, 4, 5, 6]
Array
的+=(_:_:)
泛型运算符将数组元素附加到现有数组中Array
类型拥有一个+=(_:_:)
泛型运算符。 +=(_:_:)
的声明如下:
将序列的元素附加到可替换范围的集合中。
static func += <Other>(lhs: inout Array<Element>, rhs: Other) where Other : Sequence, Self.Element == Other.Element
以下Playground示例代码展示了如何使用+=(_:_:)
泛型操作符将类型为[Int]
的数组元素附加到现有数组中:
var array1 = [1, 2, 3]
let array2 = [4, 5, 6]
array1 += array2
print(array1) // prints [1, 2, 3, 4, 5, 6]
Array
的append(contentsOf:)
方法将一个数组追加到另一个数组中Swift
中的Array
具有append(contentsOf:)
方法。 append(contentsOf:)
拥有如下声明:
将序列或集合的元素添加到此集合的末尾。
mutating func append<S>(contentsOf newElements: S) where S : Sequence, Self.Element == S.Element
以下是Playground示例代码,展示了如何使用append(contentsOf:)
方法将一个类型为[Int]
的数组附加到另一个数组中:
var array1 = [1, 2, 3]
let array2 = [4, 5, 6]
array1.append(contentsOf: array2)
print(array1) // prints [1, 2, 3, 4, 5, 6]
Sequence
的flatMap(_:)
方法将两个数组合并为一个新数组对于所有遵循Sequence
协议的类型(包括Array
),Swift提供了flatMap(_:)
方法。该方法具有以下声明:
返回一个数组,其中包含调用给定转换函数的结果,该函数针对此序列中的每个元素。
func flatMap<SegmentOfResult>(_ transform: (Self.Element) throws -> SegmentOfResult) rethrows -> [SegmentOfResult.Element] where SegmentOfResult : Sequence
以下Playground示例代码展示了如何使用flatMap(_:)
方法将两个类型为[Int]
的数组合并成一个新数组:let array1 = [1, 2, 3]
let array2 = [4, 5, 6]
let flattenArray = [array1, array2].flatMap({ (element: [Int]) -> [Int] in
return element
})
print(flattenArray) // prints [1, 2, 3, 4, 5, 6]
Sequence
的joined()
方法和Array
的init(_:)
初始化器将两个数组合并成一个新数组Swift 为所有符合 Sequence
协议(包括 Array
)的类型提供了 joined()
方法。该方法具有以下声明:
返回连接后的序列中的元素。
func joined() -> FlattenSequence<Self>
此外,Swift 的 Array
类型还有一个 init(_:)
初始化器。 init(_:)
的声明如下:创建包含序列元素的数组。init<S>(_ s: S) where Element == S.Element, S : Sequence
因此,以下的 Playground 示例代码显示了如何使用 joined()
方法和 init(_:)
初始化器将两个类型为 [Int]
的数组合并为一个新数组:
let array1 = [1, 2, 3]
let array2 = [4, 5, 6]
let flattenCollection = [array1, array2].joined() // type: FlattenBidirectionalCollection<[Array<Int>]>
let flattenArray = Array(flattenCollection)
print(flattenArray) // prints [1, 2, 3, 4, 5, 6]
#6. 使用 Array
的 reduce(_:_:)
方法将两个数组合并成一个新数组Array
有一个名为reduce(_:_:)
的方法。该方法的声明如下:
返回使用给定闭包组合序列元素的结果。
func reduce<Result>(_ initialResult: Result, _ nextPartialResult: (Result, Element) throws -> Result) rethrows -> Result
以下 Playground 代码展示了如何使用 reduce(_:_:)
方法将两个类型为 [Int]
的数组合并成一个新的数组:let array1 = [1, 2, 3]
let array2 = [4, 5, 6]
let flattenArray = [array1, array2].reduce([], { (result: [Int], element: [Int]) -> [Int] in
return result + element
})
print(flattenArray) // prints [1, 2, 3, 4, 5, 6]
+
来合并两个数组,而对于一个数组中的多个数组,我则喜欢使用 joined()
。 - Cœur+
运算符,它会生成绝对疯狂的编译时间。 - lawicko如果你不是操作符重载的铁粉,或者更喜欢函数式编程:
// use flatMap
let result = [
["merge", "me"],
["We", "shall", "unite"],
["magic"]
].flatMap { $0 }
// Output: ["merge", "me", "We", "shall", "unite", "magic"]
// ... or reduce
[[1],[2],[3]].reduce([], +)
// Output: [1, 2, 3]
自从Swift 2.0以来,我最喜欢的方法是flatten
var a:[CGFloat] = [1, 2, 3]
var b:[CGFloat] = [4, 5, 6]
let c = [a, b].flatten()
这将返回FlattenBidirectionalCollection
,因此如果您只需要一个CollectionType
,那么这将足够,并且您将免费获得惰性评估。如果您确切地需要数组,可以执行以下操作:
let c = Array([a, b].flatten())
reduce
可以用来实现flatten的行为:var a = ["a", "b", "c"]
var b = ["d", "e", "f"]
let res = [a, b].reduce([],combine:+)
在所提供的方案中,性能和内存开销上最好的选择是flatten
,它只是懒惰地包装原始数组,而不创建新的数组结构。LazyCollection
,因此懒惰的行为将无法传递到链中的下一个操作(map、flatMap、filter等)。flatten()
之前或之后添加.lazy
,例如,以这种方式修改Tomasz示例:let c = [a, b].lazy.flatten()
flatMap
,没有必要自己重新实现或使用reduce:var a:[CGFloat] = [1, 2, 3]
var b:[CGFloat] = [4, 5, 6]
let merged = [a, b].flatMap { $0 }
就是这样 - 玩得开心
Swift 4.X
我知道的最简单的方法就是直接使用加号。
var Array1 = ["Item 1", "Item 2"]
var Array2 = ["Thing 1", "Thing 2"]
var Array3 = Array1 + Array2
// Array 3 will just be them combined :)
Swift 5 数组扩展
extension Array where Element: Sequence {
func joined() -> Array<Element.Element> {
return self.reduce([], +)
}
}
例子:
let array = [[1,2,3], [4,5,6], [7,8,9]]
print(array.joined())
//result: [1, 2, 3, 4, 5, 6, 7, 8, 9]
let index = 1
if 0 ... a.count ~= index {
a[index..<index] = b[0..<b.count]
}
print(a) // [1.0, 4.0, 5.0, 6.0, 2.0, 3.0]
var arrayOne = [1,2,3]
var arrayTwo = [4,5,6]
arrayOne.append(arrayTwo)
以上代码将把arrayOne转换为单个元素,并将其添加到arrayTwo的末尾。
如果您想要的结果是:[1, 2, 3, 4, 5, 6],则:
arrayOne.append(contentsOf: arrayTwo)
[1, 2, 3, 4]
与[4, 5, 6]
合并后返回[1, 2, 3, 4, 5, 6]
,其中包含两个数组中所有元素的唯一组合? - daniel