我如何在Swift连接或合并数组?

如果在swift中创建了两个数组,就像这样:

var a:[CGFloat] = [1, 2, 3]
var b:[CGFloat] = [4, 5, 6]

如何将它们合并到[1, 2, 3, 4, 5, 6]?

313435 次浏览

你可以用+连接数组,构建一个新数组

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]

如果你不喜欢操作符重载,或者更喜欢函数类型:

// 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以来,我最喜欢的方法是

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可以用来实现的行为:

var a = ["a", "b", "c"]
var b = ["d", "e", "f"]


let res = [a, b].reduce([],combine:+)

在给出的选项中,最好的替代方案(性能/内存方面)就是flatten,它只是惰性地包装原始数组,而不创建新的数组结构。

但是请注意 不返回 a LazyCollection,这样惰性行为就不会沿着链传播到下一个操作(map, flatMap, filter,等等…)

如果懒惰在你的特定情况下是有意义的,只要记住在flatten()之前或附加.lazy就可以了,例如,这样修改Tomasz sample:

let c = [a, b].lazy.flatten()

如果你想在一个特定的索引后面插入第二个数组,你可以这样做(从Swift 2.2开始):

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]

在Swift 5中,根据你的需要,你可以选择以下六种方法中的一个来连接/合并两个数组。


# 1。使用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]

# 2。使用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]

# 3。使用Arrayappend(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]

# 4。使用SequenceflatMap(_:)方法将两个数组合并为一个新数组

Swift为所有符合Sequence协议(包括Array)的类型提供了flatMap(_:)方法。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]

# 5。使用Sequencejoined()方法和Arrayinit(_:)初始化器将两个数组合并为一个新数组

Swift为所有符合Sequence协议(包括Array)的类型提供了joined()方法。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。使用Arrayreduce(_:_:)方法将两个数组合并为一个新数组

Swift Array有一个reduce(_:_:)方法。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]

不同数据类型的Marge数组:

var arrayInt = [Int]()
arrayInt.append(6)
var testArray = ["a",true,3,"b"] as [Any]
testArray.append(someInt)

输出:

["a", true, 3, "b", "hi", 3, [6]]

斯威夫特3.0

通过使用加法运算符(+)将两个类型兼容的现有数组相加,可以创建一个新数组。新数组的类型是从你相加的两个数组的类型推断出来的,

let arr0 = Array(repeating: 1, count: 3) // [1, 1, 1]
let arr1 = Array(repeating: 2, count: 6)//[2, 2, 2, 2, 2, 2]
let arr2 = arr0 + arr1 //[1, 1, 1, 2, 2, 2, 2, 2, 2]

这是上述代码的正确结果。

这是合并两个数组的最短方法。

 var array1 = [1,2,3]
let array2 = [4,5,6]

连接/合并他们

array1 += array2
New value of array1 is [1,2,3,4,5,6]

类似地,使用数组字典可以:

var dict1 = [String:[Int]]()
var dict2 = [String:[Int]]()
dict1["key"] = [1,2,3]
dict2["key"] = [4,5,6]
dict1["key"] = dict1["key"]! + dict2["key"]!
print(dict1["key"]!)

如果“key”匹配,则可以遍历dict1并添加dict2

var arrayOne = [1,2,3]
var arrayTwo = [4,5,6]

如果你想要的结果是:[1,2,3,[4,5,6]]

arrayOne.append(arrayTwo)

上面的代码将arrayOne转换为单个元素,并将其添加到arrayTwo的末尾。

如果你想要的结果是:[1,2,3,4,5,6],那么,

arrayOne.append(contentsOf: arrayTwo)

上面的代码将arrayOne的所有元素添加到arrayTwo的末尾。

谢谢。

斯威夫特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]

所以这个问题真的需要flatMap,不需要自己重新实现一些东西或使用reduce:

var a:[CGFloat] = [1, 2, 3]
var b:[CGFloat] = [4, 5, 6]
let merged = [a, b].flatMap { $0 }

就是这样-玩得开心🙃

如果你正在处理大型序列,那么更有效的方法是使用Apple在算法包中定义的方法。

let n1 = [1, 2, 3]
let n2 = [4, 5, 6]


let allNumbers = chain(n1, n2)
for num in allNumbers {
print(num) // for loop prints 1 to 6
}


// Similarly for String type
let s = chain("foo", "BAR") // produces "fooBAR"

Chain相对于其他方法的优点:

  1. 允许混合不同的序列类型
let n = chain([10, 20, 30], 1...3) // will produce 10, 20, 30, 1, 2, 3
  1. 不进行新的内存分配

chain方法本质上迭代第一个序列,当它在第一个序列中遇到endIndex时,它就开始无缝迭代第二个序列。